package com.xayy.health.mgt.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.Method;
import cn.kawins.base.result.CheckResult;
import cn.kawins.base.result.ResultEnum;
import cn.kawins.base.utils.BeanUtil;
import cn.kawins.base.utils.CollUtil;
import cn.kawins.base.utils.HttpUtil;
import cn.kawins.base.utils.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.xayy.health.core.config.param.AlgorithmParam;
import com.xayy.health.core.config.param.DsParam;
import com.xayy.health.core.config.param.ModelFaultParams;
import com.xayy.health.core.constant.HealthManagerConstant;
import com.xayy.health.core.constant.TableNameConstant;
import com.xayy.health.core.enums.ModelTrainStatusEnum;
import com.xayy.health.core.enums.ModuleEnum;
import com.xayy.health.core.enums.MultiParameterEnum;
import com.xayy.health.core.enums.TaskStatusEnum;
import com.xayy.health.core.exception.HealthException;
import com.xayy.health.mgt.mapper.*;
import com.xayy.health.mgt.model.*;
import com.xayy.health.mgt.model.dto.*;
import com.xayy.health.mgt.model.vo.*;
import com.xayy.health.mgt.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author zhangxa
 */
@Service
@Slf4j
public class DiagnoseServiceImpl<ListTaskResultVo> implements DiagnoseService {
    /**
     * 时间间隔 ms
     */
    public static int AMOUNT_TO_ADD =500;

    @Value("${interval.time}")
    private int intervalTime;

    @Autowired
    private DsParam dsParam;
    @Autowired
    private AlgorithmParam algorithmParam;
    @Autowired
    private TelemetryDataMapper telemetryDataMapper;
    @Autowired
    private ModelTrainRecordService modelTrainRecordService;
    @Autowired
    private TaskChildInfoService taskChildInfoService;
    @Autowired
    private FaultInfoMapper faultInfoMapper;
    @Autowired
    private SatelliteNodeService satelliteNodeService;
    @Autowired
    private TaskParamInfoService taskParamInfoService;
    @Autowired
    private TaskInfoService taskInfoService;
    @Autowired
    private DiagnoseService diagnoseService;
    @Autowired
    private ModelTrainAccuracyService modelTrainAccuracyService;
    @Autowired
    private ModelAlgorithmInfoService modelAlgorithmInfoService;
    @Autowired
    private DataQualityService dataQualityService;
    @Autowired
    private DiagnoseAlgorithmManageMapper diagnoseAlgorithmManageMapper;
    @Autowired
    private MultiParameterServiceImpl multiParameterServiceImpl;

    @Autowired
    private SatelliteNodeMapper satelliteNodeMapper;
    @Autowired
    private SatelliteCodeService satelliteCodeService;

    @Autowired
    private SelectTelemetryDataSourceMapper selectTelemetryDataSourceMapper;

    @Autowired
    private FaultReportService faultReportService;

    @PostConstruct
    public void init(){
        AMOUNT_TO_ADD=intervalTime;
    }

    /**
     * 模型训练
     *
     * @param modelTrain 模型训练入参
     * @param recordId   记录id
     * @return 结果日志
     */
    @Override
    public CheckResult<Object> modelTrial(ModelTrain modelTrain, Long recordId) throws UnknownHostException {
        //组装模型参数
        List<AlgorithmParams> algorithmParamList = modelTrain.getAlgorithmParamList();
        if (CollUtil.isEmpty(algorithmParamList) || algorithmParamList.size() != HealthManagerConstant.MODEL_PARAM_LENGTH) {
            return CheckResult.fail("模型参数不能为空");
        }
        List<ModelAlgorithmInfo> modelAlgorithmInfos = assembleAlgorithmParamList(modelTrain, recordId, algorithmParamList);
        //旧模型设置模型名称
        if (StrUtil.isNotEmpty(modelTrain.getOldModelName())) {
            ModelTrainRecord modelTrainRecord = modelTrainRecordService.selectOne(ModelTrainRecord.builder().id(modelTrain.getOldModelName()).build());
            modelTrain.setModelName(modelTrainRecord.getModelName());
        }
        //判断遥测数据中是否含有空值
        String[] paramCodes =new String[]{modelTrain.getParamCode()};
        TelemetryDto telemetryDto = new TelemetryDto().setSatelliteCode(modelTrain.getSatelliteCode()).setStartTime(modelTrain.getStartTime()).setEndTime(modelTrain.getEndTime()).setParamCodes(paramCodes);
        Map<String, List<TelemetryData>> listMap = selectTelemetryData(telemetryDto);
        //判断是否存在空值
        for (Map.Entry<String, List<TelemetryData>> map : listMap.entrySet()) {
            List<TelemetryData> list = map.getValue();
            if (!CollectionUtils.isEmpty(list)) {
                for (TelemetryData data : list) {
                    if (StringUtils.isEmpty(data.getValue())) {
                        throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                    }
                }
            }
        }

        HttpResponse postResponse;
        try {
            postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.trialUrl).body(JSON.toJSONString(modelTrain)).execute();
        } catch (Exception e) {
            modelTrainRecordService.updateByIdSelective(ModelTrainRecord.builder().id(recordId.toString()).status(ModelTrainStatusEnum.ABNORMAL.getCode()).build());
            log.info(e.getMessage());
            faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"接口调用异常","接口调用异常");
            return CheckResult.fail("调用接口失败：" + e.getMessage());
        }
        if (postResponse.getStatus() != HttpStatus.HTTP_OK) {
            try {
                // 修改训练记录状态
                modelTrainRecordService.updateByIdSelective(ModelTrainRecord.builder().id(recordId.toString()).status(ModelTrainStatusEnum.ABNORMAL.getCode()).build());
                Map map = JSONObject.parseObject(postResponse.body(), Map.class);
                if (StrUtil.isEmpty(modelTrain.getOldModelName())) {
                    modelTrainRecordService.delete(ModelTrainRecord.builder().modelName(modelTrain.getModelName()).build());
                }
                log.error("调用模型训练算法结果异常");
                return CheckResult.fail(map.get("msg").toString());
            } catch (Exception e) {
                faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"调用算法异常","调用算法异常");
                return CheckResult.fail("调用算法失败，http状态码：" + postResponse.getStatus());
            }
        }
        JSONObject result = JSON.parseObject(postResponse.body());
        if (!result.getInteger(HealthManagerConstant.STATUS_CODE).equals(HttpStatus.HTTP_OK)) {
            modelTrainRecordService.updateByIdSelective(ModelTrainRecord.builder().id(recordId.toString()).status(ModelTrainStatusEnum.ABNORMAL.getCode()).build());
            return CheckResult.fail(result.getString("msg"));
        }
        // 修改训练记录状态
        Map<String, Object> data = result.getObject("data", Map.class);
        Object acc = data.get("acc");
        Object suggest = data.get("suggest");
        Object offset = data.get("offset");
        List<Map<String, String>> testModel = (List<Map<String, String>>) data.get("test_model");
        // 旧模型不插准确度数据
        if (StrUtil.isNotEmpty(modelTrain.getOldModelName())) {
            ModelTrainRecord trainRecord = BeanUtil.copyProperties(modelTrain, ModelTrainRecord.class);
            ModelTrainRecord oldModelTrainRecord = modelTrainRecordService.selectById(modelTrain.getOldModelName());
            trainRecord.setModelName(oldModelTrainRecord.getModelName()).setId(oldModelTrainRecord.getId()).setThreshold(StringUtil.toString(suggest)).setOffset(offset.toString()).setStatus(ModelTrainStatusEnum.DONE.getCode()).setAccuracy(acc.toString()).setOldModelName(oldModelTrainRecord.getModelName());
            modelTrainRecordService.updateByIdSelective(trainRecord);
            modelTrainAccuracyService.delete(ModelTrainAccuracy.builder().modelTrainRecordId(oldModelTrainRecord.getId()).build());
            updateModelTrainData(testModel, modelTrain, oldModelTrainRecord.getId(), null);
            updateAlgorithmInfo(true, oldModelTrainRecord.getId(), modelAlgorithmInfos);
        } else {
            ModelTrainRecord modelTrainRecord = ModelTrainRecord.builder().id(recordId.toString()).threshold(StringUtil.toString(suggest)).offset(offset.toString()).status(ModelTrainStatusEnum.DONE.getCode()).accuracy(acc.toString()).build();
            modelTrainRecordService.updateByIdSelective(modelTrainRecord);
            updateAlgorithmInfo(false, recordId.toString(), modelAlgorithmInfos);
            if (CollUtil.isNotEmpty(testModel)) {
                updateModelTrainData(testModel, modelTrain, null, recordId);
            }
        }
        String tableName = TableNameConstant.MODEL_TRAIN_TELEMETRY + recordId;
        selectTelemetryDataSourceMapper.createTaskTable(tableName);
        selectTelemetryDataSourceMapper.deleteTelemetryData(tableName);
        selectTelemetryDataSourceMapper.insertTelemetryListData(tableName,listMap.get(modelTrain.getParamCode()));
        //故障数据
        Object failureInfosData = null;
        if (BeanUtil.isNotEmpty(modelTrain.getDates())) {
            CheckResult<Object> failureInfos = diagnoseService.failureInfos(FailureInfoVo.builder().dates(modelTrain.getDates()).paramCode(modelTrain.getParamCode()).satelliteCode(modelTrain.getSatelliteCode()).build());
            failureInfosData = failureInfos.getData();
        }
        HashMap<String, Object> map = new HashMap<>(2);
//        if(!CollectionUtils.isEmpty(testModel)){
//            testModel=addDataToListForTrain(testModel);
//        }
        map.put("testModel", testModel);
        map.put("paramCode", modelTrain.getParamCode());
        return CheckResult.success(map);
    }
    /**
     * 补充缺失数据
     * @param taskTrendDataList 待补充集合
     * @return 补充完的集合
     */
//    public static List<Map<String, String>> addDataToListForTrain(List<Map<String, String>> taskTrendDataList) {
//        List<Map<String, String>> resList=new ArrayList<>();
//        if (CollUtil.isNotEmpty(taskTrendDataList)) {
//            if(taskTrendDataList.size()>1){
//                for(int i=0;i<taskTrendDataList.size()-1;i++){
//                    Map<String, String> dto=taskTrendDataList.get(i);
//                    Map<String, String> dto2=taskTrendDataList.get(i+1);
//                    String time1 = dto.get("time");
//                    String time2 = dto2.get("time");
//                    time1= ConvertUtils.formatTime(time1);
//                    time2=ConvertUtils.formatTime(time2);
//                    DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                    LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                    LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                    LocalDateTime timeFormatter3=timeFormatter1.plus(DiagnoseServiceImpl.AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                    dto.put("time",time1);
//                    resList.add(dto);
//                    if(timeFormatter2.isAfter(timeFormatter3)){
//                        String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                        if(16==startLocalDate.length()){
//                            startLocalDate=startLocalDate+":00";
//                        }
//                        if(!startLocalDate.contains(".")){
//                            startLocalDate=startLocalDate+".000";
//                        }
//                        Map<String, String> res=new HashMap<>();
//                        res.put("time",startLocalDate);
//                        res.put("value",null);
//                        resList.add(res);
//                    }
//                }
//                Map<String, String> taskResultVo = taskTrendDataList.get(taskTrendDataList.size() - 1);
//                taskResultVo.put("time",ConvertUtils.formatTime(taskResultVo.get("time")));
//                resList.add(taskResultVo);
//            }else {
//                Map<String, String> taskResultVo = taskTrendDataList.get(0);
//                taskResultVo.put("time",ConvertUtils.formatTime(taskResultVo.get("time")));
//                resList.add(taskResultVo);
//            }
//
//        }
//        return resList;
//    }



    /**
     * 修改模型数据
     *
     * @param testModel       准确度数据
     * @param modelTrain      模型参数
     * @param oldmodelTrainId 旧模型id
     */
    public void updateModelTrainData(List<Map<String, String>> testModel, ModelTrain modelTrain, String oldmodelTrainId, Long recordId) {
        ArrayList<ModelTrainAccuracy> telemetryList = new ArrayList<>();
        for (Map<String, String> model : testModel) {
            String time = model.get("time");
            String value = Convert.toStr(model.get("value"));
            ModelTrainAccuracy modelTrainAccuracy = ModelTrainAccuracy.builder().time(time).value(value).valueType("1").sateCode(modelTrain.getSatelliteCode()).paramCode(modelTrain.getParamCode()).build();
            if (StringUtil.isEmpty(oldmodelTrainId)) {
                modelTrainAccuracy.setModelTrainRecordId(recordId.toString());
            } else {
                modelTrainAccuracy.setModelTrainRecordId(oldmodelTrainId);
            }
            telemetryList.add(modelTrainAccuracy);
        }
        modelTrainAccuracyService.insertList(telemetryList);
    }

    /**
     * 更新算法信息
     *
     * @param isUpdate            是否是旧模型
     * @param modelId             模型id
     * @param modelAlgorithmInfos 模型信息
     */
    private void updateAlgorithmInfo(Boolean isUpdate, String modelId, List<ModelAlgorithmInfo> modelAlgorithmInfos) {
        if (Boolean.TRUE.equals(isUpdate)) {
            modelAlgorithmInfoService.delete(ModelAlgorithmInfo.builder().modelId(modelId).build());
        }
        modelAlgorithmInfoService.insertList(modelAlgorithmInfos);
    }

    /**
     * 获取遥测参数
     *
     * @param telemetryDto 遥测入参
     * @return Map<String, List < TelemetryData>>
     */
    @Override
    public Map<String, List<TelemetryData>> selectTelemetryData(TelemetryDto telemetryDto) {
        Map<String, List<TelemetryData>> result = new HashMap<>(1);
        if (BeanUtil.isEmpty(telemetryDto) || telemetryDto.getStartTime() == null || telemetryDto.getEndTime() == null) {
            return result;
        }
        String[] paramCodes = telemetryDto.getParamCodes();
        for (String paramCode : paramCodes) {
            List<TelemetryData> telemetryDataList = new ArrayList<>();
            // 获取数据有预处理结果则用没有去原始数据
            TaskParamInfo taskParamInfo = taskParamInfoService.selectOne(TaskParamInfo.builder().satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).status(1).build());
            if (BeanUtil.isNotEmpty(taskParamInfo)) {
                TaskInfo taskInfo = taskInfoService.selectById(taskParamInfo.getTaskId());
                if (null != taskInfo) {
                    telemetryDataList = getTelemetry(telemetryDto, taskInfo, paramCode);
                }
            } else {
                DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(telemetryDto.getStartTime()).endTime(telemetryDto.getEndTime()).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                telemetryDataList = satelliteNodeService.getYcList(dataFeatureDto);
            }
            result.put(paramCode, telemetryDataList);
        }
        return result;
    }

    /**
     * 获取预测数据
     *
     * @param telemetryDto 入参信息
     * @return 获取预测数据列表
     */
    @Override
    public List<TelemetryData> selectTelemetryDataByTimeRange(TelemetryDto telemetryDto) {
        DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(telemetryDto.getStartTime()).endTime(telemetryDto.getEndTime()).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(telemetryDto.getParamCode()).build();
        return satelliteNodeService.getYcList(dataFeatureDto);
    }

    /**
     * 获取遥测信息
     *
     * @param dataFeatureDto 入参信息
     * @return 结果日志
     */
    @Override
    public List<TelemetryData> getYcListByTimeRange(DataFeatureDto dataFeatureDto) {
        List<TelemetryData> ycList = telemetryDataMapper.getYcListByTimeRange(dataFeatureDto);
        return ycList;
    }

    /**
     * 查询使用后的测遥数据(自动运行或者模型训练使用后的)
     * @param telemetryDto 遥测入参
     * @return Map<String, List < TelemetryData>>
     */
    @Override
    public Map<String, List<TelemetryData>> selectUsedTelemetryData(String tableName,TelemetryDto telemetryDto) {
        Map<String, List<TelemetryData>> result = new HashMap<>(1);
        String[] paramCodes = telemetryDto.getParamCodes();
        for (String paramCode : paramCodes) {
            /*查询保存后的遥测数据*/
            telemetryDto.setParamCode(paramCode);
            List<TelemetryData> ycList = null;
            try {
                ycList = selectTelemetryDataSourceMapper.selectTelemetryListData(tableName,telemetryDto);
            } catch (Exception e) {
                log.error("selectUsedTelemetryData errors...tableName={},telemetryDto={}",tableName,telemetryDto,e);
            }
            result.put(paramCode, ycList);
        }
        return result;
    }
    /**
     * 获取平滑后数据
     * @param telemetryDto 参数对象
     * @return Map<String, List < TelemetryData>>
     */
    @Override
    public Map<String, List<TelemetryData>> selectPrePhData(TelemetryDto telemetryDto) {
        Map<String, List<TelemetryData>> result = new HashMap<>(1);
        if (BeanUtil.isEmpty(telemetryDto) || telemetryDto.getStartTime() == null || telemetryDto.getEndTime() == null) {
            return result;
        }
        String[] paramCodes = telemetryDto.getParamCodes();
        for (String paramCode : paramCodes) {
            /*构建查询对象*/
            DataFeatureDto dataFeatureDto2 = DataFeatureDto.builder()
                    .startTime(telemetryDto.getStartTime())
                    .endTime(telemetryDto.getEndTime())
                    .satelliteCode(telemetryDto.getSatelliteCode())
                    .paramCode(paramCode)
                    .build();
            /*查询该参数有没有做过预处理*/
            TaskParamInfo taskParamInfo = taskParamInfoService.selectOne(TaskParamInfo.builder().satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).status(1).build());
            if (BeanUtil.isNotEmpty(taskParamInfo)) {
                /*查询平滑数据*/
                List<TelemetryData> phList = telemetryDataMapper.getPhList(dataFeatureDto2);
                result.put(paramCode, phList);
            }
        }
        return result;
    }

    /**
     * 事后诊断和趋势预测所用入参数据获取
     *
     * @param telemetryDto 入参
     * @param taskInfo     任务时间
     * @param paramCode    参数
     * @return 结果
     */
    private List<TelemetryData> getTelemetry(TelemetryDto telemetryDto, TaskInfo taskInfo, String paramCode) {
        List<TelemetryData> telemetryDataList = new ArrayList<>();
        Date startTimeTelemetry = telemetryDto.getStartTime();
        Date endTimeTelemetry = telemetryDto.getEndTime();
        Date startTimeTask = taskInfo.getStartTime();
        Date endTimeTask = taskInfo.getEndTime();

        // 开始时间小于任务开始时间
        if (startTimeTelemetry.getTime() < startTimeTask.getTime()) {
            // 结束时间小于任务开始时间,全部查询遥测
            if (endTimeTelemetry.getTime() <= startTimeTask.getTime()) {
                DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                telemetryDataList = satelliteNodeService.getYcList(dataFeatureDto);
                return telemetryDataList;

            } else if (endTimeTelemetry.getTime() <= endTimeTask.getTime()) {
                // 结束时间小于等于任务结束时间,开始时间到任务开始时间查询遥测，任务开始时间到结束时间查处理数据
                DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(startTimeTask).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                List<TelemetryData> telemetryDataList1 = satelliteNodeService.getYcList(dataFeatureDto);

                DataFeatureDto dataFeatureDto1 = DataFeatureDto.builder().startTime(startTimeTask).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).parentTaskId(taskInfo.getId()).build();
                List<TelemetryData> telemetryDataList2 = telemetryDataMapper.getPhList(dataFeatureDto1);

                telemetryDataList.addAll(telemetryDataList1);
                telemetryDataList.addAll(telemetryDataList2);
                return telemetryDataList;
            } else {
                // 结束时间大于任务结束时间，开始时间到任务开始时间和任务结束时间到结束时间查遥测，任务时间段查处理数据
                DataFeatureDto dataFeatureDto1 = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(startTimeTask).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                List<TelemetryData> telemetryDataList1 = satelliteNodeService.getYcList(dataFeatureDto1);

                DataFeatureDto dataFeatureDto2 = DataFeatureDto.builder().startTime(endTimeTask).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).parentTaskId(taskInfo.getId()).build();
                List<TelemetryData> telemetryDataList2 = telemetryDataMapper.getPhList(dataFeatureDto2);

                DataFeatureDto dataFeatureDto3 = DataFeatureDto.builder().startTime(startTimeTask).endTime(endTimeTask).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                List<TelemetryData> telemetryDataList3 = satelliteNodeService.getYcList(dataFeatureDto3);

                telemetryDataList.addAll(telemetryDataList1);
                telemetryDataList.addAll(telemetryDataList3);
                telemetryDataList.addAll(telemetryDataList2);
                return telemetryDataList;
            }

        } else { // 开始时间大于等于任务开始时间
            if (startTimeTelemetry.getTime() > endTimeTask.getTime()) {
                // 开始时间大于任务结束时间，查询遥测
                DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                telemetryDataList = satelliteNodeService.getYcList(dataFeatureDto);
                return telemetryDataList;
            } else if (endTimeTelemetry.getTime() <= endTimeTask.getTime()) {
                // 结束时间是否小于等于任务结束时间，查询处理后的数据
                DataFeatureDto dataFeatureDto = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).parentTaskId(taskInfo.getId()).build();
                telemetryDataList = telemetryDataMapper.getPhList(dataFeatureDto);
                return telemetryDataList;
            } else {
                // 开始时间到任务结束时间查处理数据，任务结束时间到结束时间查遥测
                DataFeatureDto dataFeatureDto1 = DataFeatureDto.builder().startTime(startTimeTelemetry).endTime(endTimeTask).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).parentTaskId(taskInfo.getId()).build();
                List<TelemetryData> telemetryDataList1 = telemetryDataMapper.getPhList(dataFeatureDto1);

                DataFeatureDto dataFeatureDto2 = DataFeatureDto.builder().startTime(endTimeTask).endTime(endTimeTelemetry).satelliteCode(telemetryDto.getSatelliteCode()).paramCode(paramCode).build();
                List<TelemetryData> telemetryDataList2 = satelliteNodeService.getYcList(dataFeatureDto2);
                telemetryDataList.addAll(telemetryDataList1);
                telemetryDataList.addAll(telemetryDataList2);
                return telemetryDataList;
            }
        }

    }

    /**
     * 调用模型
     *
     * @param modelTrain 模型入参
     * @return CheckResult<?>
     */
    @Override
    public CheckResult<?> startModel(ModelTrain modelTrain) throws UnknownHostException {
        if (modelTrain.getIsCaseOne() == 0) {
            CaseOneVo caseOneVo = Convert.convert(CaseOneVo.class, modelTrain);
            return CheckResult.success(executeCaseOne(caseOneVo));
        } else {
            String url = algorithmParam.detectionUrl;
            HttpResponse postResponse;
            HashMap<String, Object> finalMap = new HashMap<>(2);
            try {
                postResponse = HttpUtil.createRequest(Method.POST, url).body(JSON.toJSONString(modelTrain)).execute();
            } catch (Exception e) {
                faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"调用接口异常","调用接口异常");
                return CheckResult.fail("调用接口失败：" + e.getMessage());
            }
            if (postResponse.getStatus() != HttpStatus.HTTP_OK) {
                try {
                    Map map = JSONObject.parseObject(postResponse.body(), Map.class);
                    log.error("调用模型算法结果异常");
                    return CheckResult.fail(map.get("msg").toString());
                } catch (Exception e) {
                    faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"调用算法异常","调用算法异常");
                    return CheckResult.fail("调用算法失败，http状态码：" + postResponse.getStatus());
                }
            }
            JSONObject result = JSON.parseObject(postResponse.body());
            if (!result.getInteger(HealthManagerConstant.STATUS_CODE).equals(HttpStatus.HTTP_OK)) {
                return CheckResult.fail(result.getString("msg"));
            }
            Map<String, Object> data = result.getObject("data", Map.class);
            Object error = data.get("error");
            List<Map<String, Object>> list = JSON.parseObject(String.valueOf(error), List.class);
            List<Map<String, Object>> originalList = JSON.parseObject(String.valueOf(data.get("original")), List.class);

//            List<String> timeList=new ArrayList<>();
            //补充原始数据
            if (!CollectionUtils.isEmpty(originalList)) {
                //originalList = DataFeatureServiceImpl.addDataList(originalList);
//                for (Map<String, Object> map : originalList) {
//                    timeList.add(map.get("time").toString());
//                }
//                Collections.sort(timeList);
                data.put("original",originalList);
            }

            List<Map<String, Object>> predictList = JSON.parseObject(String.valueOf(data.get("predict")), List.class);
            if (!CollectionUtils.isEmpty(predictList)) {
                //predictList = DataFeatureServiceImpl.addNullValue(timeList, predictList);
                data.put("predict",predictList);
            }
            ArrayList<Object> arrayList = new ArrayList<>();
            HashMap<String, Object> errorMap = new HashMap<>(2);
            if (CollUtil.isNotEmpty(list)) {
                for (Map<String, Object> map : list) {
                    for (Map<String, Object> map1 : originalList) {
                        if (map.get("time").equals(map1.get("time"))) {
                            HashMap<String, Object> hashMap = new HashMap<>(4);
                            hashMap.put("originalTime", map1.get("time"));
                            hashMap.put("originalValue", map1.get("value"));
                            hashMap.put("errorTime", map.get("time"));
                            hashMap.put("errorValue", map.get("value"));
                            for (Map<String, Object> map2 : predictList) {
                                if (map.get("time").equals(map2.get("time"))) {
                                    hashMap.put("predictTime", map2.get("time"));
                                    hashMap.put("predictValue", map2.get("value"));
                                    arrayList.add(hashMap);
                                    errorMap.put("dataList", arrayList);
                                }
                            }
                        }
                    }
                }

            } else {
                errorMap.put("dataList", new ArrayList<>());
            }
            finalMap.put("data", result.get("data"));
            finalMap.put("error", errorMap);
            return CheckResult.success(finalMap);
        }

    }

    /**
     * 事后诊断异步任务
     *
     * @param taskChildInfo 子任务信息
     * @param taskInfo      任务信息
     * @param caseOneDTO    单参数入参
     */
    @SuppressWarnings("unchecked")
    @Override
    public void asyncExcuteTask(TaskChildInfo taskChildInfo, TaskInfo taskInfo, CaseOneDTO caseOneDTO) throws UnknownHostException {
        //多参数
        if (taskInfo.getCheckMultiparameter() == 1) {
            try {
                String[] paramList = taskChildInfo.getParams().split(",");
                if (ObjectUtil.isEmpty(paramList)) {
                    throw new HealthException("上线运行参数代号为空");
                }
                String[] split = taskChildInfo.getParams().split(",");
                /*子任务 查看组装遥测数据*/
                Map<String, Object> map = assembleTelemetryListForKandTwoAndFeature(split, taskChildInfo, null, null, null,taskInfo.getOriginalDataSources());
                Map<String, Object> args = (Map<String, Object>) map.get("args");
                List<Map<String, Object>> telemetryList = (List<Map<String, Object>>) map.get("telemetryList");
                /*判断遥测是否有空值*/
                Map<String, List<TelemetryData>> telDataList = (Map<String, List<TelemetryData>>) map.get("args");
                boolean isRun = checkTelDateIsEmpty(taskInfo,telDataList,taskChildInfo);
                /*isRun 为false则不继续执行*/
                if(!isRun){
                    return;
                }
                ModelTrain modelTrain = Convert.convert(ModelTrain.class, taskInfo);
                if (taskInfo.getMultiparameterAlgName().equals(MultiParameterEnum.SLOPEALGORITHM.getCode())) {
                    log.info("斜率异常检查消耗时间开始" + DateUtil.now());
                    //斜率异常检查
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getSlopeAlgorithm()).body(JSON.toJSONString(args)).execute();
                    JSONArray jsonArrays = multiParameterServiceImpl.executionExceptionData(args, telemetryList, modelTrain, postResponse);
                    multiParameterServiceImpl.onlineParseSave(null, taskChildInfo, taskInfo.getMultiparameterAlgName(), taskInfo, jsonArrays);
                    log.info("斜率异常检查消耗时间结束" + DateUtil.now());
                } else if (taskInfo.getMultiparameterAlgName().equals(MultiParameterEnum.MEANFEATUREALGORITHM.getCode())) {
                    log.info("均值消耗时间开始" + DateUtil.now());
                    //均值特征
                    modelTrain.setTelemetryDataList(args);
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getMeanFeatureAlgorithm()).body(JSON.toJSONString(modelTrain)).execute();
                    JSONArray jsonArrays = multiParameterServiceImpl.executionExceptionData(args, telemetryList, modelTrain, postResponse);
                    AlgorithmParseDTO parseDTO = reassembleParseData(jsonArrays.getObject(0, JSONObject.class));
                    multiParameterServiceImpl.onlineParseSave(parseDTO, taskChildInfo, taskInfo.getMultiparameterAlgName(), taskInfo, null);
                    log.info("均值消耗时间结束" + DateUtil.now());
                } else if (taskInfo.getMultiparameterAlgName().equals(MultiParameterEnum.KNEARESTNEIGHBORALGORITHM.getCode())) {
                    log.info("k近邻消耗时间开始" + DateUtil.now());
                    //k近邻
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getKNearestNeighborAlgorithm()).body(JSON.toJSONString(args)).execute();
                    JSONArray jsonArrays = multiParameterServiceImpl.executionExceptionData(args, telemetryList, modelTrain, postResponse);
                    AlgorithmParseDTO parseDTO = reassembleParseData(jsonArrays.getObject(0, JSONObject.class));
                    multiParameterServiceImpl.onlineParseSave(parseDTO, taskChildInfo, taskInfo.getMultiparameterAlgName(), taskInfo, null);
                    log.info("k近邻消耗时间结束" + DateUtil.now());
                } else if (taskInfo.getMultiparameterAlgName().equals(MultiParameterEnum.TWOPARAMETERDIAGNOSISALGORITHM.getCode())) {
                    log.info("双参数诊断消耗时间开始" + DateUtil.now());
                    //双参数诊断
                    TelemetryDto telemetryDto = new TelemetryDto().setSatelliteCode(modelTrain.getSatelliteCode()).setStartTime(modelTrain.getNormalStartTime()).setEndTime(modelTrain.getNormalEndTime()).setParamCodes(split);
                    Map<String, List<TelemetryData>> listMap = null;
                    /*1 ：预处理平滑后的遥测数据 ，其他：原始遥测数据*/
                    if(taskInfo.getOriginalDataSources() != null && 1 == taskInfo.getOriginalDataSources()){
                        listMap = selectPrePhData(telemetryDto);
                    }else{
                        listMap = selectTelemetryData(telemetryDto);
                    }
                    modelTrain.setNormalTimeTelemetryDataList(listMap);
                    modelTrain.setTelemetryDataList(args);
                    if (Boolean.TRUE.equals(dsParam.getTwoParameterAddEightHour())) {
                        modelTrain.setNormalStartTime(DateUtil.offsetHour(modelTrain.getNormalStartTime(), 8));
                        modelTrain.setNormalEndTime(DateUtil.offsetHour(modelTrain.getNormalEndTime(), 8));
                    }
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getTwoParameterDiagnosisAlgorithm()).body(JSON.toJSONString(modelTrain)).execute();
                    JSONArray jsonArrays = multiParameterServiceImpl.executionExceptionData(args, telemetryList, modelTrain, postResponse);
                    JSONObject algorithmParamObject = jsonArrays.getObject(0, JSONObject.class);
                    multiParameterServiceImpl.insertTwoOnline(paramList, algorithmParamObject, taskChildInfo, taskInfo);
                    log.info("双参数诊断消耗时间结束" + DateUtil.now());
                } else if (taskInfo.getMultiparameterAlgName().equals(MultiParameterEnum.THRESHOLDJUDGMENTALGORITHM.getCode())) {
                    log.info("门限判断算法消耗时间开始" + DateUtil.now());
                    //门限判断算法
                    modelTrain.setTelemetryDataList(args);
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getThresholdJudgmentAlgorithm()).body(JSON.toJSONString(modelTrain)).execute();
                    JSONArray jsonArrays = multiParameterServiceImpl.executionExceptionData(args, telemetryList, modelTrain, postResponse);
                    JSONObject algorithmParamObject = jsonArrays.getObject(0, JSONObject.class);
                    multiParameterServiceImpl.insertThresholdJudgmentOnline(paramList, algorithmParamObject, taskChildInfo, taskInfo);
                    log.info("门限判断算法消耗时间结束" + DateUtil.now());
                }
                // 插入子任务数据
                taskChildInfo.setStatus(TaskStatusEnum.DONE.getCode());
                taskChildInfoService.updateByIdSelective(taskChildInfo);
                /*插入所用遥测数据*/
                String tableName = TableNameConstant.RUN_TASK_TELEMETRY + taskChildInfo.getId();
                selectTelemetryDataSourceMapper.createTaskTable(tableName);
                telDataList.forEach((k,v) ->{
                    selectTelemetryDataSourceMapper.insertTelemetryListData(tableName,v);
                });
            } catch (Exception e) {
                e.printStackTrace();
                taskChildInfo.setDataSituation("无");
                taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
                taskChildInfoService.updateByIdSelective(taskChildInfo);
                faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"任务执行失败异常","任务执行异常");
                log.error("任务:{} 执行失败! 异常信息:{}", taskChildInfo.getName(), ExceptionUtil.getMessage(e));
            }
        } else {
            /*查询遥测*/
            TelemetryDto telemetryDto = new TelemetryDto();
            telemetryDto.setSatelliteCode(taskChildInfo.getSatelliteCode());
            telemetryDto.setParamCodes((new String[]{taskChildInfo.getParams()}));
            telemetryDto.setStartTime(taskChildInfo.getStartTime());
            telemetryDto.setEndTime(taskChildInfo.getEndTime());
            /*1 ：预处理平滑后的遥测数据 ，其他：原始遥测数据*/
            Map<String, List<TelemetryData>> taskPlanTelemetry = new HashMap<>(8);
            if(taskInfo.getOriginalDataSources() != null && 1 == taskInfo.getOriginalDataSources()){
                taskPlanTelemetry = selectPrePhData(telemetryDto);
            }else{
                taskPlanTelemetry = selectTelemetryData(telemetryDto);
            }
            /*查询遥测是否有空值*/
            boolean isRun = checkTelDateIsEmpty(taskInfo,taskPlanTelemetry,taskChildInfo);
            /*isRun 为false则不继续执行*/
            if(!isRun){
                return;
            }
            //0是案例一
            if (taskInfo.getIsCaseOne() == 0) {
                //上线运行
                singleParameterDiagnosisOnline(taskChildInfo, taskInfo, caseOneDTO);
                log.info("单参数诊断插入完成" + DateUtil.now());
            } else {
                //单参
                List<ModelTrainRecord> modelTrainRecords = modelTrainRecordService.select(ModelTrainRecord.builder().modelType(2).modelName(taskChildInfo.getModelName()).satelliteCode(taskInfo.getSatelliteCode()).build());
                if (CollUtil.isEmpty(modelTrainRecords)) {
                    throw new HealthException("模型不存在!");
                }
                // 模型门限
                String threshold = modelTrainRecords.get(0).getThreshold();

                ModelTrain modelTrain = ModelTrain.builder().satelliteMid("").satelliteCode(taskChildInfo.getSatelliteCode()).startTime(taskChildInfo.getStartTime()).endTime(taskChildInfo.getEndTime()).modelName(taskChildInfo.getModelName()).paramCode(taskChildInfo.getParams()).threshold(threshold).paramCodes(CollUtil.newArrayList(taskChildInfo.getParams())).build();
                String url = algorithmParam.detectionUrl;
                try {
                    HttpResponse postResponse = HttpUtil.createRequest(Method.POST, url).body(JSON.toJSONString(modelTrain)).execute();
                    if (postResponse.getStatus() != HttpStatus.HTTP_OK) {
                        taskChildInfo.setDataSituation("无");
                        taskChildInfoService.updateByIdSelective(taskChildInfo);
                        log.error("调用算法失败，http状态码：" + postResponse.getStatus());
                        return;
                    }
                    JSONObject result = JSON.parseObject(postResponse.body());
                    if (!result.getInteger(HealthManagerConstant.STATUS_CODE).equals(HttpStatus.HTTP_OK)) {
                        taskChildInfo.setDataSituation("无");
                        taskChildInfoService.updateByIdSelective(taskChildInfo);
                        log.error("算法业务错误：" + result.getString("msg"));
                        return;
                    }
                    Map<String, Object> data = result.getObject("data", Map.class);
                    //预测数据
                    List<Map<String, Object>> perdictList = JSON.parseObject(String.valueOf(data.get("predict")), List.class);
                    List<DiagnoseFaultData> perdictDataList = new ArrayList<>(CollUtil.isNotEmpty(perdictList) ? perdictList.size() : 0);
                    perdictList.forEach(x -> {
                        DiagnoseFaultData diagnoseFaultData = new DiagnoseFaultData();
                        diagnoseFaultData.setTaskId(taskChildInfo.getId());
                        diagnoseFaultData.setSateCode(taskChildInfo.getSatelliteCode());
                        diagnoseFaultData.setParamCode(taskChildInfo.getParams());
                        diagnoseFaultData.setTime(x.get("time").toString());
                        diagnoseFaultData.setValue(Double.parseDouble(x.get("value").toString()));
                        perdictDataList.add(diagnoseFaultData);
                    });
                    if (CollUtil.isNotEmpty(perdictDataList) && perdictDataList.size() > 0) {
                        taskChildInfo.setDataSituation("(" + perdictDataList.get(0).getTime() + "," + perdictDataList.get(perdictDataList.size() - 1).getTime() + ")");
                    }

                    faultInfoMapper.insertDiagnosePredictDataList(perdictDataList);

                    //异常数据
                    List<Map<String, Object>> list = JSON.parseObject(String.valueOf(data.get("error")), List.class);
                    List<DiagnoseFaultData> diagnoseFaultDataList = new ArrayList<>(CollUtil.isNotEmpty(list) ? list.size() : 0);
                    list.forEach(x -> {
                        DiagnoseFaultData diagnoseFaultData = new DiagnoseFaultData();
                        diagnoseFaultData.setTaskId(taskChildInfo.getId());
                        diagnoseFaultData.setSateCode(taskChildInfo.getSatelliteCode());
                        diagnoseFaultData.setParamCode(taskChildInfo.getParams());
                        diagnoseFaultData.setTime(x.get("time").toString());
                        diagnoseFaultData.setValue(Double.parseDouble(x.get("value").toString()));
                        diagnoseFaultDataList.add(diagnoseFaultData);
                    });
                    if (CollUtil.isNotEmpty(diagnoseFaultDataList)) {
                        taskChildInfo.setErrorSituation("1");
                        faultInfoMapper.insertDiagnoseFaultDataList(diagnoseFaultDataList);
                    } else {
                        taskChildInfo.setErrorSituation("0");
                    }
                    taskChildInfoService.updateByIdSelective(taskChildInfo);
                    // 插入clickhouse数据
                    taskChildInfo.setStatus(TaskStatusEnum.DONE.getCode());
                    taskChildInfo.setErrorNum(list.size());
                    taskInfoService.updateByIdSelective(taskInfo);
                    taskChildInfoService.updateByIdSelective(taskChildInfo);
                    /*插入所用遥测数据*/
                    String tableName = TableNameConstant.RUN_TASK_TELEMETRY + taskChildInfo.getId();
                    selectTelemetryDataSourceMapper.createTaskTable(tableName);
                    taskPlanTelemetry.forEach((k,v) ->{
                        selectTelemetryDataSourceMapper.insertTelemetryListData(tableName,v);
                    });
                } catch (Exception e) {
                    taskChildInfo.setDataSituation("无");
                    taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
                    taskChildInfoService.updateByIdSelective(taskChildInfo);
                    faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"任务执行失败异常","任务执行异常");
                    log.error("任务:{} 执行失败! 异常信息:{}", taskChildInfo.getName(), ExceptionUtil.getMessage(e));
                    e.printStackTrace();
                }
            }

        }
    }

    /**
     *  判断遥测是否有空值
     * @param taskInfo 任务信息
     * @param telDataList 遥测数据
     * @param taskChildInfo 子任务信息
     * @return boolean
     */
    private boolean checkTelDateIsEmpty(TaskInfo taskInfo, Map<String, List<TelemetryData>> telDataList,TaskChildInfo taskChildInfo) {
        /*定义返回值*/
        AtomicBoolean isContinue = new AtomicBoolean(true);
        /*判断是选择的原始数据还是预处理数据*/
        if(taskInfo.getOriginalDataSources() != null && 1 == taskInfo.getOriginalDataSources()){
            /* 如果是选择数据处理后的数据
             * a.如果此时间段数据已经处理，则看下是否存在空值，有空值则停止该任务的进行
             * b.如果数据处理此参数还没处理此时间段则该任务停上一个所选该参数数据处理时任务的周期，周期过后，若还没数据，则运行下一个子任务
             */
            if(CollUtil.isEmpty(telDataList)){
                /*如果预处理数据为空，并且已经等待一个周期则直接停止子任务，并且配置为异常*/
                if(1 != taskInfo.getPauseEndTimeIsExecute()){
                    /*设置状态为异常*/
                    taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
                    taskChildInfo.setMsg("事后诊断-自动运行，检查预处理数据结果无数据");
                    taskChildInfoService.updateByIdSelective(taskChildInfo);
                    isContinue.set(false);
                }else{
                    /*如果预处理数据为空，并且没有等待一个周期则等下个周期在运行*/
                    isContinue.set(false);
                    /*将TaskInfo 运行时间向前推一个周期*/
                    Date runTime = DateUtil.offsetMinute(taskInfo.getLongRunningTime(), -(int) (Double.parseDouble(taskInfo.getCycle()) * 60));
                    taskInfo.setLongRunningTime(runTime);
                    /*修改任务暂停到何时字段，下阶段开始运行,下阶段开始任务执行在 ScheduledTask类中checkTaskIsRun()方法定时任务检测是否到点，到点则开始执行任务 */
                    Date nextRuntime = DateUtil.offsetMinute(new Date(), (int) (Double.parseDouble(taskInfo.getCycle()) * 60));
                    taskInfo.setPauseEndTime(nextRuntime);
                    taskInfo.setPauseEndTimeIsExecute(0);
                    /*修改任务状态为停止*/
                    taskInfo.setStatus(0);
                    /*修改任务运行时间*/
                    taskInfoService.updateByIdSelective(taskInfo);
                }
            }else{
                telDataList.forEach((k, v) -> {
                    if(CollUtil.isNotEmpty(v)){
                        long count = v.stream().filter(f -> StringUtil.isBlank(f.getValue())).count();
                        if(count > 0){
                            /*如果预处理数据出现空值数据则插入子任务数据并且停止该任务*/
                            /*设置状态为异常*/
                            taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
                            taskChildInfo.setMsg("事后诊断-自动运行，检查预处理数据结果【"+"参数 " + k + " 存在空值,数据串："+v.toString()+"】");
                            taskChildInfoService.updateByIdSelective(taskChildInfo);
                            isContinue.set(false);
                        }
                    }
                });
            }
        }else{
            /*如果是原始数据则需要检查是否有空值，有的话此周期的子任务停止
             *需要判断数据中是否存在空值，如果存在空值，则此周期的子任务停止，查看子任务时显示下由于存在空值所以这个任务没有数据，接着跑一个周期任务。原因放在msg中，查询时前端展示出来
             */
            telDataList.forEach((k, v) -> {
                if(CollUtil.isNotEmpty(v)){
                    long count = v.stream().filter(f -> StringUtil.isBlank(f.getValue())).count();
                    if(count > 0){
                        /*如果遥测出现空值数据则插入子任务数据并且停止该任务*/
                        /*设置状态为异常*/
                        taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
                        taskChildInfo.setMsg("事后诊断-自动运行，检查原始遥测结果【"+"参数 " + k + " 存在空值,数据串："+v.toString()+"】");
                        taskChildInfoService.updateByIdSelective(taskChildInfo);
                        isContinue.set(false);
                    }
                }
            });
        }
        return isContinue.get();
    }


    /**
     * 获取子任务异常点集合
     *
     * @param taskId 任务id
     * @return 结果日志
     */
    @Override
    public List<TaskResultVo> getTaskFaultDataList(Long taskId) {
        return faultInfoMapper.getTaskFaultDataList(taskId);
    }


    /**
     * 事后诊断模型训练多短故障数据获取
     *
     * @param failureInfoVo 故障信息入参
     * @return CheckResult<Object>
     */
    @Override
    public CheckResult<Object> failureInfos(FailureInfoVo failureInfoVo) {
        List<List<TelemetryData>> result = new ArrayList<>();
        List<ModelFaultParams> dates = failureInfoVo.getDates();
        if (CollUtil.isEmpty(dates)) {
            return CheckResult.success();
        }
        dates.forEach(date -> {
            Date errorStart = date.getErrorStart();
            Date errorEnd = date.getErrorEnd();
            if (BeanUtil.isNotEmpty(errorStart) && BeanUtil.isNotEmpty(errorEnd)) {
                TelemetryDto telemetryDto = new TelemetryDto();
                telemetryDto.setSatelliteCode(failureInfoVo.getSatelliteCode());
                telemetryDto.setParamCode(failureInfoVo.getParamCode());
                telemetryDto.setParamCodes(new String[]{failureInfoVo.getParamCode()});
                telemetryDto.setStartTime(errorStart);
                telemetryDto.setEndTime(errorEnd);
                Map<String, List<TelemetryData>> telemetryData = selectTelemetryData(telemetryDto);
                List<TelemetryData> infos = telemetryData.get(failureInfoVo.getParamCode());
//                if(!CollectionUtils.isEmpty(infos)){
//                    infos= addDataToList(infos);
//                }
                result.add(infos);
            }
        });
        return CheckResult.success(result);
    }

//    /**
//     * 补充缺失数据
//     * @param taskTrendDataList 待补充集合
//     * @return 补充完的集合
//     */
//    private List<TelemetryData> addDataToList(List<TelemetryData> taskTrendDataList) {
//        List<TelemetryData> resList=new ArrayList<>();
//        if (CollUtil.isNotEmpty(taskTrendDataList)) {
//            if(taskTrendDataList.size()>1){
//                for(int i=0;i<taskTrendDataList.size()-1;i++){
//                    TelemetryData dto=taskTrendDataList.get(i);
//                    TelemetryData dto2=taskTrendDataList.get(i+1);
//                    String time1 = dto.getTime();
//                    String time2 = dto2.getTime();
//                    time1= ConvertUtils.formatTime(time1);
//                    time2=ConvertUtils.formatTime(time2);
//                    DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                    LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                    LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                    LocalDateTime timeFormatter3=timeFormatter1.plus(DiagnoseServiceImpl.AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                    dto.setTime(time1);
//                    resList.add(dto);
//                    if(timeFormatter2.isAfter(timeFormatter3)){
//                        String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                        if(16==startLocalDate.length()){
//                            startLocalDate=startLocalDate+":00";
//                        }
//                        if(!startLocalDate.contains(".")){
//                            startLocalDate=startLocalDate+".000";
//                        }
//                        TelemetryData res=new TelemetryData();
//                        res.setTime(startLocalDate);
//                        resList.add(res);
//                    }
//                }
//                TelemetryData taskResultVo = taskTrendDataList.get(taskTrendDataList.size() - 1);
//                taskResultVo.setTime(ConvertUtils.formatTime(taskResultVo.getTime()));
//                resList.add(taskResultVo);
//            }else {
//                TelemetryData taskResultVo = taskTrendDataList.get(0);
//                taskResultVo.setTime(ConvertUtils.formatTime(taskResultVo.getTime()));
//                resList.add(taskResultVo);
//            }
//
//        }
//        return resList;
//    }

    /**
     * 组装模型参数列表数据
     *
     * @param modelTrain 模型入参
     * @return List<ModelAlgorithmInfo>
     */
    public List<ModelAlgorithmInfo> assembleAlgorithmParamList(ModelTrain modelTrain, Long recordId, List<AlgorithmParams> algorithmParamList) {
        algorithmParamList.sort(Comparator.comparing(AlgorithmParams::getId));
        DiagnoseUpdateModelParam diagnoseUpdateModelParam = new DiagnoseUpdateModelParam();
        diagnoseUpdateModelParam.setUnits(algorithmParamList.get(0).getParamValueEnd());
        diagnoseUpdateModelParam.setActivation(algorithmParamList.get(1).getParamValueEnd());
        diagnoseUpdateModelParam.setLossMetric(algorithmParamList.get(2).getParamValueEnd());
        diagnoseUpdateModelParam.setOptimizer(algorithmParamList.get(3).getParamValueEnd());
        diagnoseUpdateModelParam.setEpochs(algorithmParamList.get(4).getParamValueEnd());
        diagnoseUpdateModelParam.setBatchSize(algorithmParamList.get(5).getParamValueEnd());
        modelTrain.setDiagnoseUpdateModelParams(diagnoseUpdateModelParam);
        List<ModelAlgorithmInfo> modelAlgorithmInfos = new ArrayList<>(algorithmParamList.size());
        algorithmParamList.forEach(x -> {
            ModelAlgorithmInfo modelAlgorithmInfo = BeanUtil.copyBean(x, ModelAlgorithmInfo.class);
            modelAlgorithmInfo.setModelId(recordId.toString());
            if (StrUtil.isNotEmpty(modelTrain.getOldModelName())) {
                modelAlgorithmInfo.setModelId(modelTrain.getOldModelName());
            }
            modelAlgorithmInfo.setId(null);
            modelAlgorithmInfos.add(modelAlgorithmInfo);
        });
        return modelAlgorithmInfos;
    }


    /**
     * 多参数算法名称列表
     *
     * @return ArrayList<Map < String, String>>
     */
    @Override
    public CheckResult<Object> getAlgorithmNameList(Integer type) {
        return CheckResult.success(diagnoseAlgorithmManageMapper.selectListByType(type));
    }

    /**
     * 事后诊断自动运行查看子任务数据(单参)
     *
     * @param taskFaultPredictDataVo 故障预测数据入参
     * @return CheckResult<?>
     */
    @Override
    public CheckResult<?> getTaskFaultPredictDataList(TaskFaultPredictDataVo taskFaultPredictDataVo) {
        SatelliteCode satelliteCode = satelliteCodeService.selectOne(SatelliteCode.builder().satelliteCode(taskFaultPredictDataVo.getSatelliteCode()).build());
        String searchKey = "";
        if (BeanUtil.isNotEmpty(satelliteCode)){
            searchKey = satelliteCode.getSatelliteName();
        }
        if (taskFaultPredictDataVo.getIsCaseOne() == 0) {
            List<MultiparatersDTO> singleParameterDiagnosisVoList = faultInfoMapper.selectCaseOneDataList(taskFaultPredictDataVo);
            Map<String, List<MultiparatersDTO>> collected = singleParameterDiagnosisVoList.stream().collect(Collectors.groupingBy(MultiparatersDTO::getType));
            ArrayList<Object> series = new ArrayList<>();
            List<String> xAxis = new LinkedList<>();
            List<MultiparatersDTO> missionGraphArrayListPre = collected.get("missiongraph");
            List<MultiparatersDTO> restGraphArrayListPre = collected.get("restgraph");
            //执行任务上下线
            List<MultiparatersDTO> detectMissionUpList = collected.get("detectMissionUp");
            List<MultiparatersDTO> detectMissionDownList = collected.get("detectMissionDown");
            //间隙任务上下线
            List<MultiparatersDTO> detectRestUpList = collected.get("detectRestUp");
            List<MultiparatersDTO> detectRestDownList = collected.get("detectRestDown");
            //散点
            List<MultiparatersDTO> scatterMissionList = collected.get("scatterMission");
            List<MultiparatersDTO> scatterRestList = collected.get("scatterRest");

            ArrayList<Object> missionValueList = new ArrayList<>();
            HashMap<String, Object> missionHashMap = new HashMap<>(3);

            Map<String,String> dateMap=new HashMap<>();
            Map<String,String> xMap=new HashMap<>();

            //上下限相减
            List<MultiparatersDTO> missionSubtractList=dataSubtractList(detectMissionUpList, detectMissionDownList);
            List<MultiparatersDTO> restSubtractList=dataSubtractList(detectRestUpList, detectRestDownList);


            //补数据
            if (CollUtil.isNotEmpty(missionGraphArrayListPre)) {
                //获取完整x轴
                for (MultiparatersDTO xMission : missionGraphArrayListPre) {
                    String time = xMission.getTime();
                    if(!xMap.containsKey(time)){
                        xMap.put(time,"");
                        xAxis.add(time);
                    }

                }
            }
            if (CollUtil.isNotEmpty(restGraphArrayListPre)) {

                for (MultiparatersDTO xRest : restGraphArrayListPre) {
                    String time = xRest.getTime();
                    if(!xMap.containsKey(time)){
                        xMap.put(time,"");
                        xAxis.add(time);
                    }

                }
            }

            xAxis.sort(Comparator.comparing(x -> DateUtil.parse(x, "yyyy-MM-dd HH:mm:ss.SSS").getTime()));
            if (CollUtil.isNotEmpty(missionGraphArrayListPre)) {
                for (MultiparatersDTO missionGraph : missionGraphArrayListPre) {
                    ArrayList<Object> missionList = new ArrayList<>();
                    String time = missionGraph.getTime();
                    if(!dateMap.containsKey(time)){
                        dateMap.put(time,"");
                        missionList.add(time);
                        missionList.add(missionGraph.getValue());
                        missionValueList.add(missionList);
                    }
                }

                //List<Object>  missionGraphChangeMap = addData(xAxis, missionValueList);

                missionHashMap.put("data", missionValueList);
                missionHashMap.put("name", taskFaultPredictDataVo.getParamCode());
                missionHashMap.put("type", "line");
                series.add(missionHashMap);
            } else {
                series.add(new HashMap<String, Object>(2));
            }

            HashMap<String, Object> restGraphHashMap = new HashMap<>(3);
            ArrayList<Object> restGraphValueList = new ArrayList<>();
            if (CollUtil.isNotEmpty(restGraphArrayListPre)) {
                for (MultiparatersDTO restGraphListDTO : restGraphArrayListPre) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    if(!dateMap.containsKey(time)){
                        restGraphList.add(time);
                        restGraphList.add(restGraphListDTO.getValue());
                        restGraphValueList.add(restGraphList);
                    }
                }

                restGraphHashMap.put("data", restGraphValueList);
                restGraphHashMap.put("name", taskFaultPredictDataVo.getParamCode());
                restGraphHashMap.put("type", "line");
                series.add(restGraphHashMap);
            } else {
                series.add(new HashMap<String, Object>(2));
            }
            //前端要求数据与修改前保持一致
            series.add(new HashMap<String, Object>(2));
            //执行上下限
            ArrayList<Object> finDetectMissionUpList = new ArrayList<>();
            if(!CollectionUtils.isEmpty(detectMissionUpList)){
                detectMissionUpList=addNullValueToMultiparatersDTO(xAxis,detectMissionUpList);
                for (MultiparatersDTO restGraphListDTO : detectMissionUpList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finDetectMissionUpList.add(restGraphList);
                }
            }
            ArrayList<Object> finDetectMissionDownList = new ArrayList<>();
            if(!CollectionUtils.isEmpty(detectMissionDownList)){
                detectMissionDownList = addNullValueToMultiparatersDTO(xAxis, detectMissionDownList);
                for (MultiparatersDTO restGraphListDTO : detectMissionDownList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finDetectMissionDownList.add(restGraphList);

                }
            }
            ArrayList<Object> finDetectRestUpList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(detectRestUpList)) {
                detectRestUpList = addNullValueToMultiparatersDTO(xAxis, detectRestUpList);
                for (MultiparatersDTO restGraphListDTO : detectRestUpList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finDetectRestUpList.add(restGraphList);

                }
            }
            ArrayList<Object> finDetectRestDownList= new ArrayList<>();
            if(!CollectionUtils.isEmpty(detectRestDownList)){
                detectRestDownList = addNullValueToMultiparatersDTO(xAxis, detectRestDownList);
                for (MultiparatersDTO restGraphListDTO : detectRestDownList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finDetectRestDownList.add(restGraphList);

                }
            }
            //执行上下线相减
            ArrayList<Object> finMissionSubtractList= new ArrayList<>();
            if(!CollectionUtils.isEmpty(missionSubtractList)){
                missionSubtractList = addNullValueToMultiparatersDTO(xAxis, missionSubtractList);
                for (MultiparatersDTO restGraphListDTO : missionSubtractList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finMissionSubtractList.add(restGraphList);
                }
            }

            ArrayList<Object> finRestSubtractList= new ArrayList<>();
            if(!CollectionUtils.isEmpty(restSubtractList)){
                restSubtractList = addNullValueToMultiparatersDTO(xAxis, restSubtractList);
                for (MultiparatersDTO restGraphListDTO : restSubtractList) {
                    ArrayList<Object> restGraphList = new ArrayList<>();
                    String time = restGraphListDTO.getTime();
                    restGraphList.add(time);
                    restGraphList.add(restGraphListDTO.getValue());
                    finRestSubtractList.add(restGraphList);
                }
            }




            HashMap<String, Object> scatterMissionMap = new HashMap<>();
            HashMap<String, Object> restMissionMap = new HashMap<>();
            ArrayList<Object> scatterValueList = new ArrayList<>();
            ArrayList<Object> scatterRestValueList = new ArrayList<>();
            if (CollUtil.isNotEmpty(scatterMissionList)) {
                for (MultiparatersDTO scatterDTO : scatterMissionList) {
                    ArrayList<Object> scatterDTOList = new ArrayList<>();
                    scatterDTOList.add(scatterDTO.getTime());
                    scatterDTOList.add(scatterDTO.getValue());
                    scatterValueList.add(scatterDTOList);
                }
                scatterMissionMap.put("data", scatterValueList);
                scatterMissionMap.put("name", taskFaultPredictDataVo.getParamCode());
                scatterMissionMap.put("type", "scatterMission");
            }
            if (CollUtil.isNotEmpty(scatterRestList)) {
                for (MultiparatersDTO scatterDTO : scatterRestList) {
                    ArrayList<Object> scatterDTOList = new ArrayList<>();
                    scatterDTOList.add(scatterDTO.getTime());
                    scatterDTOList.add(scatterDTO.getValue());
                    scatterRestValueList.add(scatterDTOList);
                }
                restMissionMap.put("data", scatterRestValueList);
                restMissionMap.put("name", taskFaultPredictDataVo.getParamCode());
                restMissionMap.put("type", "scatterRest");
            }
            TaskChildInfo taskChildInfo = taskChildInfoService.selectById(taskFaultPredictDataVo.getTaskChildId());
            String msg=taskChildInfo.getMsg();
            Map<String, Object> build = MapUtil.builder(new HashMap<String, Object>())
                    .put("xAxis", xAxis)
                    .put("series", series)
                    .put("scatterMission", scatterMissionMap)
                    .put("scatterRest", restMissionMap)
                    .put("detectMissionUp", finMissionSubtractList)
                    .put("detectMissionDown", finDetectMissionDownList)
                    .put("detectRestUp", finRestSubtractList)
                    .put("detectRestDown", finDetectRestDownList)
                    .put("msg", msg)
                    .put("searchKey", searchKey)
                    .put("gradientMap", new HashMap<>()).build();
            return CheckResult.success(build);
        } else {
            HashMap<String, Object> finalMap = new HashMap<>(2);
            TelemetryDto dto = BeanUtil.copyBean(taskFaultPredictDataVo, TelemetryDto.class);
            Map<String, List<TelemetryData>> telemetryMap = selectTelemetryData(dto);
            List<String> allTimeList=new ArrayList<>();
            if (MapUtil.isNotEmpty(telemetryMap)) {
                //telemetryMap=addDataToListMap(telemetryMap);
                for(Map.Entry<String, List<TelemetryData>> map: telemetryMap.entrySet()){
                    List<TelemetryData> valueList = map.getValue();
                    if(!CollectionUtils.isEmpty(valueList)){
                        valueList=valueList.stream().distinct().sorted(Comparator.comparing(TelemetryData::getTime)).collect(Collectors.toList());
                        for(TelemetryData data:valueList){
                            allTimeList.add(data.getTime());
                        }
                   }
                }
                finalMap.put("telemetryMap", telemetryMap);
            } else {
                finalMap.put("telemetryMap", new HashMap<>(2));
            }
            List<TaskResultVo> faultDataList = faultInfoMapper.getTaskFaultDataList(taskFaultPredictDataVo.getTaskChildId());
            if (CollUtil.isNotEmpty(faultDataList)) {
                finalMap.put("faultDataList", faultDataList);
                TaskChildInfo taskChildInfo = taskChildInfoService.selectById(taskFaultPredictDataVo.getTaskChildId());
                if (BeanUtil.isNotEmpty(taskChildInfo)){
                    TaskInfo taskInfo = taskInfoService.selectById(taskChildInfo.getTaskId());
                    if (BeanUtil.isNotEmpty(taskInfo)){
                        String paramCodeName = taskInfo.getParamCodeName();
                        searchKey +=paramCodeName;
                    }
                }
            } else {
                finalMap.put("faultDataList", new ArrayList<>());
            }
            List<TaskResultVo> predictDataList = faultInfoMapper.getPredictDataList(taskFaultPredictDataVo.getTaskChildId());
            if (CollUtil.isNotEmpty(predictDataList)) {
                if(!allTimeList.isEmpty()) {
                    predictDataList = CalculateServiceImpl.addNullValue(allTimeList, predictDataList);
                }
                finalMap.put("predictDataList", predictDataList);
            } else {
                finalMap.put("predictDataList", new ArrayList<>());
            }
            finalMap.put("searchKey", searchKey);
            return CheckResult.success(finalMap);
        }

    }

    /**
     * 算法返回数据上限减去下限
     * @param detectMissionUpList 上限数据
     * @param detectMissionDownList 下限数据
     * @return 相减后的数据
     */
    private  List<MultiparatersDTO> dataSubtractList(List<MultiparatersDTO> detectMissionUpList, List<MultiparatersDTO> detectMissionDownList) {
        List<MultiparatersDTO> dataSubtractList=new ArrayList<>();
        if(!CollectionUtils.isEmpty(detectMissionUpList)){
            for(int i = 0; i< detectMissionUpList.size(); i++){
                MultiparatersDTO upDto= detectMissionUpList.get(i);
                MultiparatersDTO downDto= detectMissionDownList.get(i);
                Double upValue=upDto.getValue();
                Double downValue=downDto.getValue();
                if(null==upValue){
                    upValue=0.00D;
                }
                if(null==downValue){
                    downValue=0.00D;

                }
                MultiparatersDTO subtractDto=new MultiparatersDTO();
                subtractDto.setTime(upDto.getTime());
                subtractDto.setValue(upValue-downValue);
                dataSubtractList.add(subtractDto);
            }
        }
        return dataSubtractList;
    }


    /**
     * 补充数据
     *
     * @param xAxis 横坐标
     * @param list  需要补充的数据
     * @return 补充后结果
     */
    public   static List<MultiparatersDTO> addNullValueToMultiparatersDTO(List<String> xAxis, List<MultiparatersDTO> list) {
        List<MultiparatersDTO> finalList = new ArrayList<>();
        if (null != list) {
            Map<Object, MultiparatersDTO> map = new HashMap<>();
            for (MultiparatersDTO vo : list) {
                map.put(vo.getTime(), vo);
            }
            for (String xa : xAxis) {
                if (map.containsKey(xa)) {
                    finalList.add(map.get(xa));
                } else {
                    MultiparatersDTO vo=new MultiparatersDTO();
                    vo.setTime(xa);
                    vo.setValue(null);
                    finalList.add(vo);
                }

            }

        }

        return finalList;
    }

    /**
     * 事后诊断自动运行查看子任务数据(分页)
     *
     * @param taskFaultPredictDataVo 故障预测数据入参
     * @return Object
     */
    @Override
    public Object getTaskFaultPredictPageList(TaskFaultPredictDataVo taskFaultPredictDataVo) {
        CheckResult<?> checkResult = getTaskFaultPredictDataList(taskFaultPredictDataVo);
        Map resultMap = (Map) checkResult.getData();
        Map<String, List<TelemetryData>> telemetryMap = (Map<String, List<TelemetryData>>) resultMap.get("telemetryMap");
        List<TaskResultVo> predictDataList = (List<TaskResultVo>) resultMap.get("predictDataList");
        TaskChildInfo childInfo = taskChildInfoService.selectOne(TaskChildInfo.builder().id(taskFaultPredictDataVo.getTaskChildId()).build());
        TaskInfo taskInfo = taskInfoService.selectOne(TaskInfo.builder().id(childInfo.getTaskId()).build());
        ModelTrainRecord modelTrainRecord = modelTrainRecordService.selectOne(ModelTrainRecord.builder().modelName(taskInfo.getModelName()).modelType(2).build());
        HashMap<String, Object> finalMap = new HashMap<>(4);
        PageMethod.startPage(taskFaultPredictDataVo.getPage(), taskFaultPredictDataVo.getSize());
        List<TaskResultVo> faultDataArrayList = faultInfoMapper.getTaskFaultDataList(taskFaultPredictDataVo.getTaskChildId());
        PageInfo<TaskResultVo> pageInfo = new PageInfo<>(faultDataArrayList);
        String[] paramCodes = taskFaultPredictDataVo.getParamCodes();

        HashMap<String, Object> errorMap = new HashMap<>(4);
        ArrayList<Map<String, Object>> arrayList = new ArrayList<>();
        if (CollUtil.isNotEmpty(faultDataArrayList)) {
            for (String code : paramCodes) {
                List<TelemetryData> telemetryDataList = telemetryMap.get(code);
                for (TelemetryData telemetryData : telemetryDataList) {
                    for (TaskResultVo faultData : faultDataArrayList) {
                        if (faultData.getTime().equals(telemetryData.getTime())) {
                            Map<String, Object> hashMap = new HashMap<>(4);
                            hashMap.put("originalTime", telemetryData.getTime());
                            hashMap.put("originalValue", telemetryData.getValue());
                            hashMap.put("errorTime", faultData.getTime());
                            hashMap.put("errorValue", faultData.getValue());
                            for (TaskResultVo predictData : predictDataList) {
                                if (faultData.getTime().equals(predictData.getTime())) {
                                    hashMap.put("predictTime", predictData.getTime());
                                    hashMap.put("predictValue", predictData.getValue());
                                    arrayList.add(hashMap);
                                    errorMap.put("dataList", arrayList);
                                }
                            }
                        }
                    }
                }
            }
        } else {
            errorMap.put("dataList", new ArrayList<>());
        }
        finalMap.put("satelliteCode", taskInfo.getSatelliteCode());
        finalMap.put("modelName", taskInfo.getModelName());
        finalMap.put("compare", modelTrainRecord.getOffset());
        finalMap.put("paramCode", modelTrainRecord.getParamCode());
        finalMap.put("error", errorMap);
        errorMap.put("total", pageInfo.getTotal());
        errorMap.put("pageSize", pageInfo.getPageSize());
        return CheckResult.success(finalMap);
    }

    /**
     * 单参数手动试算
     *
     * @param caseOneVo 单参数入参
     * @return Map<String, Object>
     */
    public Map<String, Object> executeCaseOne(CaseOneVo caseOneVo) throws UnknownHostException {
        /*处理单参数算法入参*/
        CaseOneDTO caseOneDTO = assembleCaseOneParam(caseOneVo);
        //案例一算法
        HashMap<String, Object> finalMap = new HashMap<>(4);
        ArrayList<Object> finalList = new ArrayList<>();
        HttpResponse postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.singleParameterAlgorithm).body(JSON.toJSONString(caseOneDTO)).execute();
        if (postResponse.getStatus() != HttpStatus.HTTP_OK) {
            // 返回为空默认为解析失败
            throw new HealthException("算法调用失败");
        }
        JSONArray jsonArrays = null;
        JSONObject map = null;
        try {
            jsonArrays = JSONArray.parseArray(postResponse.body());
        } catch (Exception e) {
            faultReportService.faultReport(ModuleEnum.QSYC.getCode(), ModuleEnum.SHZD.getMsg(),"算法异常","算法执行异常");
            map = JSONObject.parseObject(postResponse.body(), JSONObject.class);
            if (map.getInteger(HealthManagerConstant.STATUS_CODE).equals(ResultEnum.FAIL.getCode())) {
                throw new HealthException(map.getString("msg"));
            }
        }

        List parseObject = JSONObject.parseObject(postResponse.body(), List.class);
        SingleParameterDiagnosisVo singleParameterDiagnosisVo = JSON.parseObject(JSON.toJSONString(parseObject.get(0)), SingleParameterDiagnosisVo.class);
        Map<String, String> dateMap = new HashMap<>(2);
        Map<String, String> xMap = new HashMap<>(2);
        List<SingleParameterDiagnosisVo.downMissionDTO> missionGraphDTOListPre = singleParameterDiagnosisVo.getDownMissionDTOList();
        //下图执行下限
        List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionDown=singleParameterDiagnosisVo.getDetectMissionDown();
        //下图执行上限
        List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionUp=singleParameterDiagnosisVo.getDetectMissionUp();

        List<String> xAxis = new ArrayList<>();
        ArrayList<Object> missionGraphArrayList = new ArrayList<>();
        ArrayList<Object> restGraphArrayList = new ArrayList<>();
        HashMap<String, Object> missionGraphHashMap = new HashMap<>(3);
        //下图间隙
        List<SingleParameterDiagnosisVo.downRestDTO> restGraphDTOListPre = singleParameterDiagnosisVo.getDownRestDTOList();
        //下图间隙上限
        List<SingleParameterDiagnosisVo.downMissionDTO> detectRestUpList= singleParameterDiagnosisVo.getDetectRestUp();
        //下图间隙下限
        List<SingleParameterDiagnosisVo.downMissionDTO> detectRestDownList=singleParameterDiagnosisVo.getDetectRestDown();

        //上下限相减
        List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionUpSubtractList=downMissionDataSubtractList(detectMissionUp, detectMissionDown);
        List<SingleParameterDiagnosisVo.downMissionDTO> detectRestUpSubtractList=downMissionDataSubtractList(detectRestUpList, detectRestDownList);



       // List<SingleParameterDiagnosisVo.downRestDTO> restGraphDTOList = new ArrayList<>();
            if (CollUtil.isNotEmpty(restGraphDTOListPre)) {
//                if(restGraphDTOListPre.size()>1){
//                    for(int i=0;i<restGraphDTOListPre.size()-1;i++){
//                        SingleParameterDiagnosisVo.downRestDTO dto=restGraphDTOListPre.get(i);
//                        SingleParameterDiagnosisVo.downRestDTO dto2=restGraphDTOListPre.get(i+1);
//                        String time1 = dto.getTime();
//                        String time2 = dto2.getTime();
//                        time1= ConvertUtils.formatTime(time1);
//                        time2=ConvertUtils.formatTime(time2);
//                        DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                        LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                        LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                        LocalDateTime timeFormatter3=timeFormatter1.plus(AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                        dto.setTime(time1);
//                        restGraphDTOList.add(dto);
//                        if(timeFormatter2.isAfter(timeFormatter3)){
//                            String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                            if(16==startLocalDate.length()){
//                                startLocalDate=startLocalDate+":00";
//                            }
//                            if(!startLocalDate.contains(".")){
//                                startLocalDate=startLocalDate+".000";
//                            }
//                            SingleParameterDiagnosisVo.downRestDTO res=new SingleParameterDiagnosisVo.downRestDTO();
//                            res.setTime(startLocalDate);
//                            restGraphDTOList.add(res);
//                        }
//                    }
//                    SingleParameterDiagnosisVo.downRestDTO downRestDTO = restGraphDTOListPre.get(restGraphDTOListPre.size() - 1);
//                    downRestDTO.setTime(ConvertUtils.formatTime(downRestDTO.getTime()));
//                    restGraphDTOList.add(downRestDTO);
//                }else{
//                    SingleParameterDiagnosisVo.downRestDTO downRestDTO = restGraphDTOListPre.get(0);
//                    downRestDTO.setTime(ConvertUtils.formatTime(downRestDTO.getTime()));
//                    restGraphDTOList.add(downRestDTO);
//                }



            for (SingleParameterDiagnosisVo.downRestDTO restGraphDTO : restGraphDTOListPre) {
                String time = restGraphDTO.getTime();
                if (!xMap.containsKey(time)) {
                    xMap.put(time, "");
                    xAxis.add(time);
                }
            }
        }
     //   List<SingleParameterDiagnosisVo.downMissionDTO> missionGraphDTOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(missionGraphDTOListPre)) {
//            if(missionGraphDTOListPre.size()>1){
//                for(int i=0;i<missionGraphDTOListPre.size()-1;i++){
//                    SingleParameterDiagnosisVo.downMissionDTO dto=missionGraphDTOListPre.get(i);
//                    SingleParameterDiagnosisVo.downMissionDTO dto2=missionGraphDTOListPre.get(i+1);
//                    String time1 = dto.getTime();
//                    String time2 = dto2.getTime();
//                    time1= ConvertUtils.formatTime(time1);
//                    time2=ConvertUtils.formatTime(time2);
//                    DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                    LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                    LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                    LocalDateTime timeFormatter3=timeFormatter1.plus(AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                    dto.setTime(time1);
//                    missionGraphDTOList.add(dto);
//                    if(timeFormatter2.isAfter(timeFormatter3)){
//                        String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                        if(16==startLocalDate.length()){
//                            startLocalDate=startLocalDate+":00";
//                        }
//                        if(!startLocalDate.contains(".")){
//                            startLocalDate=startLocalDate+".000";
//                        }
//                        SingleParameterDiagnosisVo.downMissionDTO res=new SingleParameterDiagnosisVo.downMissionDTO();
//                        res.setTime(startLocalDate);
//                        missionGraphDTOList.add(res);
//                    }
//                }
//                SingleParameterDiagnosisVo.downMissionDTO downMissionDTO = missionGraphDTOListPre.get(missionGraphDTOListPre.size() - 1);
//                downMissionDTO.setTime(ConvertUtils.formatTime(downMissionDTO.getTime()));
//                missionGraphDTOList.add(downMissionDTO);
//            }else{
//                SingleParameterDiagnosisVo.downMissionDTO downMissionDTO = missionGraphDTOListPre.get(0);
//                downMissionDTO.setTime(ConvertUtils.formatTime(downMissionDTO.getTime()));
//                missionGraphDTOList.add(downMissionDTO);
//            }


            for (SingleParameterDiagnosisVo.downMissionDTO missionGraphDTO : missionGraphDTOListPre) {
                String time = missionGraphDTO.getTime();
                if (!xMap.containsKey(time)) {
                    xMap.put(time, "");
                    xAxis.add(time);
                }
            }
        }
        //间隙段
        if (CollUtil.isNotEmpty(missionGraphDTOListPre)) {
            for (SingleParameterDiagnosisVo.downMissionDTO missionGraphDTO : missionGraphDTOListPre) {
                List<Object> missionGraphList = new ArrayList<>();
                String time = missionGraphDTO.getTime();
                if (!dateMap.containsKey(time)) {
                    dateMap.put(time, "");
                    missionGraphList.add(time);
                    missionGraphList.add(missionGraphDTO.getValue());
                    missionGraphArrayList.add(missionGraphList);
                }
            }
            List<Object> changeMap = addData(xAxis, missionGraphArrayList);
            missionGraphHashMap.put("name", caseOneVo.getParamCodes()[0]);
            missionGraphHashMap.put("type", "line");
            missionGraphHashMap.put("data", changeMap);
            finalList.add(missionGraphHashMap);
        } else {
            Map<String, Object> missionGraphEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", caseOneVo.getParamCodes()[0])
                    .put("type", "line")
                    .put("data", new ArrayList<Object>())
                    .build();
            finalList.add(missionGraphEmptyMap);
        }

        //执行段
        HashMap<String, Object> restGraphHashMap = new HashMap<>(3);
        if (CollUtil.isNotEmpty(restGraphDTOListPre)) {
            for (SingleParameterDiagnosisVo.downRestDTO restGraphDTO : restGraphDTOListPre) {
                List<Object> restGraphList = new ArrayList<>();
                String time = restGraphDTO.getTime();
                if (!dateMap.containsKey(time)) {
                    restGraphList.add(time);
                    restGraphList.add(restGraphDTO.getValue());
                    restGraphArrayList.add(restGraphList);
                }
            }
            List<Object> changeMap = addData(xAxis, restGraphArrayList);
            restGraphHashMap.put("name", caseOneVo.getParamCodes()[0]);
            restGraphHashMap.put("type", "line");
            restGraphHashMap.put("data", changeMap);
            finalList.add(restGraphHashMap);
        } else {
            Map<String, Object> restGraphEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", caseOneVo.getParamCodes()[0])
                    .put("type", "line")
                    .put("data", new ArrayList<Object>())
                    .build();
            finalList.add(restGraphEmptyMap);
        }

        //上下限补数据

        List<Object> detectMissionDownList=new ArrayList<>();
        List<Object> detectMissionUpList=new ArrayList<>();
        List<Object> finDetectRestUpList=new ArrayList<>();
        List<Object> finDetectRestDownList=new ArrayList<>();

        List<Object> finDetectMissionUpSubtractList=new ArrayList<>();
        List<Object> finDetectRestUpSubtractList=new ArrayList<>();

        if(!CollectionUtils.isEmpty(detectMissionDown)){
            getFinalList(detectMissionDown, xAxis, detectMissionDownList);
        }

        if(!CollectionUtils.isEmpty(detectMissionUp)){
            getFinalList(detectMissionUp, xAxis, detectMissionUpList);
        }

        if(!CollectionUtils.isEmpty(detectRestUpList)){
            getFinalList(detectRestUpList, xAxis, finDetectRestUpList);
        }

        if(!CollectionUtils.isEmpty(detectRestDownList)){
            getFinalList(detectRestDownList, xAxis, finDetectRestDownList);
        }

        if(!CollectionUtils.isEmpty(detectMissionUpSubtractList)){
            getFinalList(detectMissionUpSubtractList, xAxis, finDetectMissionUpSubtractList);
        }

        if(!CollectionUtils.isEmpty(detectRestUpSubtractList)){
            getFinalList(detectRestUpSubtractList, xAxis, finDetectRestUpSubtractList);
        }

        //down 散点数据
        HashMap<String, Object> scatterHashMap = new HashMap<>(3);
        List<Object> scatterRestArrayList = new ArrayList<>();
        List<Object> scatterMissionArrayList = new ArrayList<>();
        //间隙异常(下图显示)
        List<SingleParameterDiagnosisVo.ScatterDTO> scatterRestList=singleParameterDiagnosisVo.getScatterRest();
        //执行异常(下图显示)
        List<SingleParameterDiagnosisVo.ScatterDTO> scatterMissionList=singleParameterDiagnosisVo.getScatterMission();

        HashMap<String, Object> scatterMissionHashMap = new HashMap<>(3);
        //执行异常(下图显示)
        if (CollUtil.isNotEmpty(scatterMissionList)) {
            for (SingleParameterDiagnosisVo.ScatterDTO scatterDTO : scatterMissionList) {
                ArrayList<Object> scatterList = new ArrayList<>();
                scatterList.add(scatterDTO.getTime());
                scatterList.add(scatterDTO.getValue());
                scatterMissionArrayList.add(scatterList);
            }
            scatterMissionHashMap.put("name", "执行散点");
            scatterMissionHashMap.put("type", "scatterMission");
            scatterMissionHashMap.put("data", scatterMissionArrayList);
            finalList.add(scatterMissionHashMap);
        } else {
            Map<String, Object> scatterMissionEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", "执行散点")
                    .put("type", "scatterMission")
                    .put("data", new ArrayList<Object>())
                    .build();
            finalList.add(scatterMissionEmptyMap);
        }

        if (CollUtil.isNotEmpty(scatterRestList)) {
            for (SingleParameterDiagnosisVo.ScatterDTO scatterDTO : scatterRestList) {
                ArrayList<Object> scatterList = new ArrayList<>();
                scatterList.add(scatterDTO.getTime());
                scatterList.add(scatterDTO.getValue());
                scatterRestArrayList.add(scatterList);
            }
            scatterHashMap.put("name", "间隙散点");
            scatterHashMap.put("type", "scatterRest");
            scatterHashMap.put("data", scatterRestArrayList);
            finalList.add(scatterHashMap);
        } else {
            Map<String, Object> scatterEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", "间隙散点")
                    .put("type", "scatterRest")
                    .put("data", new ArrayList<Object>())
                    .build();
            finalList.add(scatterEmptyMap);
        }
//        detectMissionDown 下图执行下限
//        detectMissionUp 下图执行上限
//        detectRestUp 下图间隙上限
//        detectRestDown 下图间隙下限
        finalMap.put("detectMissionDown",detectMissionDownList);
//        finalMap.put("detectMissionUp",detectMissionUpList);
//        finalMap.put("detectRestUp",finDetectRestUpList);
        finalMap.put("detectMissionUp",finDetectMissionUpSubtractList);
        finalMap.put("detectRestUp",finDetectRestUpSubtractList);
        finalMap.put("detectRestDown",finDetectRestDownList);
        finalMap.put("xAxis", xAxis);
        finalMap.put("series", finalList);
        finalMap.put("msg",singleParameterDiagnosisVo.getMsg());
        upData(singleParameterDiagnosisVo, caseOneVo,finalMap);
        return finalMap;
    }

    /**
     * 前段返回数据转换
     * @param detectMissionDown 转换前数据
     * @param xAxis 时间线
     * @param detectMissionDownList 最终结果
     */
    private static void getFinalList(List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionDown, List<String> xAxis, List<Object> detectMissionDownList) {
        detectMissionDown =addNullDataForDownMission(xAxis, detectMissionDown);
        for (SingleParameterDiagnosisVo.downMissionDTO missionGraphDTO : detectMissionDown) {
            List<Object> missionGraphList = new ArrayList<>();
            String time = missionGraphDTO.getTime();
            missionGraphList.add(time);
            missionGraphList.add(missionGraphDTO.getValue());
            detectMissionDownList.add(missionGraphList);
        }
    }


    /**
     * 算法返回数据上限减去下限
     * @param detectMissionUpList 上限数据
     * @param detectMissionDownList 下限数据
     * @return 相减后的数据
     */
    private  List<SingleParameterDiagnosisVo.downMissionDTO> downMissionDataSubtractList(List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionUpList, List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionDownList) {
        List<SingleParameterDiagnosisVo.downMissionDTO> dataSubtractList=new ArrayList<>();
        if(!CollectionUtils.isEmpty(detectMissionUpList)){
            for(int i = 0; i< detectMissionUpList.size(); i++){
                SingleParameterDiagnosisVo.downMissionDTO upDto= detectMissionUpList.get(i);
                SingleParameterDiagnosisVo.downMissionDTO downDto= detectMissionDownList.get(i);
                Double upValue=upDto.getValue();
                Double downValue=downDto.getValue();
                if(null==upValue){
                    upValue=0.00D;
                }
                if(null==downValue){
                    downValue=0.00D;

                }
                SingleParameterDiagnosisVo.downMissionDTO subtractDto=new SingleParameterDiagnosisVo.downMissionDTO();
                subtractDto.setTime(upDto.getTime());
                subtractDto.setValue(upValue-downValue);
                dataSubtractList.add(subtractDto);
            }
        }
        return dataSubtractList;
    }

//    /**
//     * 补充数据
//     *
//     * @param xAxis 横坐标
//     * @param list  需要补充的数据
//     * @return 补充后结果
//     */
    public   static List<SingleParameterDiagnosisVo.downMissionDTO> addNullDataForDownMission(List<String> xAxis, List<SingleParameterDiagnosisVo.downMissionDTO> list) {
        List<SingleParameterDiagnosisVo.downMissionDTO> finalList = new ArrayList<>();
        if (null != list) {
            Map<Object, SingleParameterDiagnosisVo.downMissionDTO> map = new HashMap<>();
            for (SingleParameterDiagnosisVo.downMissionDTO vo : list) {
                map.put(vo.getTime(), vo);
            }
            for (String xa : xAxis) {
                if (map.containsKey(xa)) {
                    finalList.add(map.get(xa));
                } else {
                    SingleParameterDiagnosisVo.downMissionDTO vo=new SingleParameterDiagnosisVo.downMissionDTO();
                    vo.setTime(xa);
                    vo.setValue(null);
                    finalList.add(vo);
                }

            }

        }

        return finalList;
    }


    public void upData(SingleParameterDiagnosisVo singleParameterDiagnosisVo, CaseOneVo caseOneVo,HashMap<String, Object> finalMap) {
        Map<String, String> cfData = new HashMap<>(2);
        Map<String, String> upXmap = new HashMap<>(3);
        List<String> upAxis = new ArrayList<>();
        List<Object> upMissionGraphArrayList = new ArrayList<>();

        HashMap<String, Object> upMissionGraphHashMap = new HashMap<>(3);
        List<Object> upFinalList = new ArrayList<>();
        //上图 整合x轴
        List<SingleParameterDiagnosisVo.UpRestDTO> upRestDTOListPre = singleParameterDiagnosisVo.getUpRestDTOList();
        //上图间隙上限
        List<SingleParameterDiagnosisVo.downMissionDTO> trainRestUpList=singleParameterDiagnosisVo.getTrainRestUp();
        //上图间隙下限
        List<SingleParameterDiagnosisVo.downMissionDTO> trainRestDownList=singleParameterDiagnosisVo.getTrainRestDown();




       // List<SingleParameterDiagnosisVo.UpRestDTO> upRestDTOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(upRestDTOListPre)) {

//            if(upRestDTOListPre.size()>1){
//                for(int i=0;i<upRestDTOListPre.size()-1;i++){
//                    SingleParameterDiagnosisVo.UpRestDTO dto=upRestDTOListPre.get(i);
//                    SingleParameterDiagnosisVo.UpRestDTO dto2=upRestDTOListPre.get(i+1);
//                    String time1 = dto.getTime();
//                    String time2 = dto2.getTime();
//                    time1= ConvertUtils.formatTime(time1);
//                    time2=ConvertUtils.formatTime(time2);
//                    DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                    LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                    LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                    LocalDateTime timeFormatter3=timeFormatter1.plus(DiagnoseServiceImpl.AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                    dto.setTime(time1);
//                    upRestDTOList.add(dto);
//                    if(timeFormatter2.isAfter(timeFormatter3)){
//                        String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                        if(16==startLocalDate.length()){
//                            startLocalDate=startLocalDate+":00";
//                        }
//                        if(!startLocalDate.contains(".")){
//                            startLocalDate=startLocalDate+".000";
//                        }
//                        SingleParameterDiagnosisVo.UpRestDTO res=new SingleParameterDiagnosisVo.UpRestDTO();
//                        res.setTime(startLocalDate);
//                        upRestDTOList.add(res);
//                    }
//                }
//                SingleParameterDiagnosisVo.UpRestDTO upRestDTO = upRestDTOListPre.get(upRestDTOListPre.size() - 1);
//                upRestDTO.setTime(ConvertUtils.formatTime(upRestDTO.getTime()));
//                upRestDTOList.add(upRestDTO);
//            }else{
//                SingleParameterDiagnosisVo.UpRestDTO upRestDTO = upRestDTOListPre.get(0);
//                upRestDTO.setTime(ConvertUtils.formatTime(upRestDTO.getTime()));
//                upRestDTOList.add(upRestDTO);
//            }

            for (SingleParameterDiagnosisVo.UpRestDTO upRestDTO : upRestDTOListPre) {
                String time = upRestDTO.getTime();
                if (!upXmap.containsKey(time)) {
                    upXmap.put(time, "");
                    upAxis.add(time);
                }
            }
        }

        List<SingleParameterDiagnosisVo.UpMissionDTO> upMissionDTOListPre = singleParameterDiagnosisVo.getUpMissionDTOList();
        //上图执行上限
        List<SingleParameterDiagnosisVo.downMissionDTO> trainMissionUpList=singleParameterDiagnosisVo.getTrainMissionUp();
        //上图执行下限
        List<SingleParameterDiagnosisVo.downMissionDTO> trainMissionDownList=singleParameterDiagnosisVo.getTrainMissionDown();

        //上下限相减
        List<SingleParameterDiagnosisVo.downMissionDTO> trainRestUpSubtractList=downMissionDataSubtractList(trainRestUpList, trainRestDownList);
        List<SingleParameterDiagnosisVo.downMissionDTO> trainMissionUpSubtractList=downMissionDataSubtractList(trainMissionUpList, trainMissionDownList);

        //List<SingleParameterDiagnosisVo.UpMissionDTO> upMissionDTOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(upMissionDTOListPre)) {

//            if(upMissionDTOListPre.size()>1){
//                for(int i=0;i<upMissionDTOListPre.size()-1;i++){
//                    SingleParameterDiagnosisVo.UpMissionDTO dto=upMissionDTOListPre.get(i);
//                    SingleParameterDiagnosisVo.UpMissionDTO dto2=upMissionDTOListPre.get(i+1);
//                    String time1 = dto.getTime();
//                    String time2 = dto2.getTime();
//                    time1= ConvertUtils.formatTime(time1);
//                    time2=ConvertUtils.formatTime(time2);
//                    DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                    LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                    LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                    LocalDateTime timeFormatter3=timeFormatter1.plus(DiagnoseServiceImpl.AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                    dto.setTime(time1);
//                    upMissionDTOList.add(dto);
//                    if(timeFormatter2.isAfter(timeFormatter3)){
//                        String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                        if(16==startLocalDate.length()){
//                            startLocalDate=startLocalDate+":00";
//                        }
//                        if(!startLocalDate.contains(".")){
//                            startLocalDate=startLocalDate+".000";
//                        }
//                        SingleParameterDiagnosisVo.UpMissionDTO res=new SingleParameterDiagnosisVo.UpMissionDTO();
//                        res.setTime(startLocalDate);
//                        upMissionDTOList.add(res);
//                    }
//                }
//                SingleParameterDiagnosisVo.UpMissionDTO upMissionDTO = upMissionDTOListPre.get(upMissionDTOListPre.size() - 1);
//                upMissionDTO.setTime(ConvertUtils.formatTime(upMissionDTO.getTime()));
//                upMissionDTOList.add(upMissionDTO);
//            }else{
//                SingleParameterDiagnosisVo.UpMissionDTO upMissionDTO = upMissionDTOListPre.get(0);
//                upMissionDTO.setTime(ConvertUtils.formatTime(upMissionDTO.getTime()));
//                upMissionDTOList.add(upMissionDTO);
//            }

            for (SingleParameterDiagnosisVo.UpMissionDTO upMissionDTO : upMissionDTOListPre) {
                String time = upMissionDTO.getTime();
                if (!upXmap.containsKey(time)) {
                    upXmap.put(time, "");
                    upAxis.add(time);
                }
            }
        }

        //上图执行段
        if (CollUtil.isNotEmpty(upMissionDTOListPre)) {
            for (SingleParameterDiagnosisVo.UpMissionDTO upMissionDto : upMissionDTOListPre) {
                List<Object> upMissionGraphList = new ArrayList<>();
                String time = upMissionDto.getTime();
                if (!cfData.containsKey(time)) {
                    cfData.put(time, "");
                    upMissionGraphList.add(time);
                    upMissionGraphList.add(upMissionDto.getValue());
                    upMissionGraphArrayList.add(upMissionGraphList);
                }
            }

            List<Object> upMissionChangeMap = addData(upAxis, upMissionGraphArrayList);
            upMissionGraphHashMap.put("name", caseOneVo.getParamCodes()[0]);
            upMissionGraphHashMap.put("type", "line");
            upMissionGraphHashMap.put("data", upMissionChangeMap);
            upFinalList.add(upMissionGraphHashMap);
        } else {

            Map<String, Object> upMissionGraphEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", caseOneVo.getParamCodes()[0])
                    .put("type", "line")
                    .put("data", new ArrayList<Object>())
                    .build();
            upFinalList.add(upMissionGraphEmptyMap);
        }
        //上限与下限补数据

        List<Object> finTrainRestUpList=new ArrayList<>();
        getUpPictureRes(trainRestUpList, upAxis, finTrainRestUpList);

        List<Object> finTrainRestDownList=new ArrayList<>();
        getUpPictureRes(trainRestDownList, upAxis, finTrainRestDownList);
        List<Object> finTrainMissionUpList=new ArrayList<>();
        getUpPictureRes(trainMissionUpList, upAxis, finTrainMissionUpList);
        List<Object> finTrainMissionDownList=new ArrayList<>();
        getUpPictureRes(trainMissionDownList, upAxis, finTrainMissionDownList);


        List<Object> finTrainRestUpSubtractList=new ArrayList<>();
        getUpPictureRes(trainRestUpSubtractList, upAxis, finTrainRestUpSubtractList);

        List<Object> finTrainMissionUpSubtractList=new ArrayList<>();
        getUpPictureRes(trainMissionUpSubtractList, upAxis, finTrainMissionUpSubtractList);




        //上图间歇段
        List<Object> upRestGraphArrayList = new ArrayList<>();
        HashMap<String, Object> upRestGraphHashMap = new HashMap<>(3);
        if (CollUtil.isNotEmpty(upRestDTOListPre)) {
            for (SingleParameterDiagnosisVo.UpRestDTO upRestDTO : upRestDTOListPre) {
                List<Object> upRestGraphList = new ArrayList<>();
                String time = upRestDTO.getTime();
                if (!cfData.containsKey(time)) {
                    upRestGraphList.add(time);
                    upRestGraphList.add(upRestDTO.getValue());
                    upRestGraphArrayList.add(upRestGraphList);
                }
            }
            List<Object> upRestChangeMap = addData(upAxis, upRestGraphArrayList);
            upRestGraphHashMap.put("name", caseOneVo.getParamCodes()[0]);
            upRestGraphHashMap.put("type", "line");
            upRestGraphHashMap.put("data", upRestChangeMap);
            upFinalList.add(upRestGraphHashMap);
        } else {
            Map<String, Object> upRestGraphEmptyMap = MapUtil.builder(new HashMap<String, Object>(2))
                    .put("name", caseOneVo.getParamCodes()[0])
                    .put("type", "line")
                    .put("data", new ArrayList<Object>())
                    .build();
            upFinalList.add(upRestGraphEmptyMap);
        }

//        trainRestUpList 上图间隙上限
//        trainRestDown 上图间隙下限
//        trainMissionUp  上图执行上限
//        trainMissionDown 上图执行下限
        finalMap.put("upFinalList", upFinalList);
//        finalMap.put("trainRestUpList", finTrainRestUpList);
        finalMap.put("trainRestUpList", finTrainRestUpSubtractList);
        finalMap.put("trainRestDown", finTrainRestDownList);
        finalMap.put("trainMissionUp", finTrainMissionUpSubtractList);
//        finalMap.put("trainMissionUp", finTrainMissionUpList);
        finalMap.put("trainMissionDown", finTrainMissionDownList);
        finalMap .put("upAxis", upAxis);
    }

    /**
     * 手动试算上图前台返回结果组装
     * @param trainMissionDownList 原始数据
     * @param upAxis 时间线
     * @param finTrainMissionDownList 最终结果
     */
    private static void getUpPictureRes(List<SingleParameterDiagnosisVo.downMissionDTO> trainMissionDownList, List<String> upAxis, List<Object> finTrainMissionDownList) {
        if(!CollectionUtils.isEmpty(trainMissionDownList)){
            trainMissionDownList =addNullDataForDownMission(upAxis, trainMissionDownList);
            for (SingleParameterDiagnosisVo.downMissionDTO scatterDTO : trainMissionDownList) {
                ArrayList<Object> scatterList = new ArrayList<>();
                scatterList.add(scatterDTO.getTime());
                scatterList.add(scatterDTO.getValue());
                finTrainMissionDownList.add(scatterList);
            }
        }
    }

    /**
     * 补充数据
     *
     * @param xAxis 横坐标
     * @param list  需要补充的数据
     * @return 补充后结果
     */
    public static <T> List<Object> addData(List<String> xAxis, List<T> list) {
        List<Object> finalList = new ArrayList<>();
        if (null != list) {
            Map<Object, Object> map = new HashMap<>();
            for (T array : list) {
                List listArray = (ArrayList) array;
                Object time = listArray.get(0);
                map.put(time, listArray);
            }

            for (String xa : xAxis) {
                if (map.containsKey(xa)) {
                    finalList.add(map.get(xa));
                } else {
                    List<Object> arrayList = new ArrayList<>();
                    arrayList.add(xa);
                    arrayList.add(null);
                    finalList.add(arrayList);
                }

            }

        }

        return finalList;
    }


    /**
     * 组装单参数算法入参
     *
     * @return CaseOneDTO
     */
    public CaseOneDTO assembleCaseOneParam(CaseOneVo caseOneVo) throws UnknownHostException {
        CaseOneDTO caseOneDTO = Convert.convert(CaseOneDTO.class, caseOneVo);
        HashMap<String, List<Map<String, List<TelemetryData>>>> telemetryMap = new HashMap<>(2);
        List<TimeDto> learnMultiTerminalTime = caseOneVo.getLearnMultiTerminalTime();
        //学习段-遥测
        List<Map<String, List<TelemetryData>>> learnTelemetryDataList = new ArrayList<>();
        //间隔段-遥测
        List<Map<String, List<TelemetryData>>> intervalTimePeriodTelemetry = new ArrayList<>();
        ArrayList<TimeDto> intervalTimePeriodList = new ArrayList<>();
        TelemetryDto telemetryDto = TelemetryDto.builder().satelliteCode(caseOneVo.getSatelliteCode()).paramCodes(caseOneVo.getParamCodes()).build();
        if (learnMultiTerminalTime.size() >= 2) {
            for (int i = 0; i < learnMultiTerminalTime.size(); i++) {
                if (i < learnMultiTerminalTime.size() - 1) {
                    //学习间隙段
                    Date intervalTimePeriodStartTime = learnMultiTerminalTime.get(i).getStartTime();
                    Date intervalTimePeriodEndTime = learnMultiTerminalTime.get(i + 1).getEndTime();
                    telemetryDto.setStartTime(intervalTimePeriodStartTime);
                    telemetryDto.setEndTime(intervalTimePeriodEndTime);
                    intervalTimePeriodList.add(TimeDto.builder().startTime(intervalTimePeriodStartTime).endTime(intervalTimePeriodEndTime).build());
                    Map<String, List<TelemetryData>> intervalTelemetryData = selectTelemetryData(telemetryDto);
                    //判断是否存在空值
                    for (Map.Entry<String, List<TelemetryData>> map : intervalTelemetryData.entrySet()) {
                        List<TelemetryData> list = map.getValue();
                        if (!CollectionUtils.isEmpty(list)) {
                            for (TelemetryData data : list) {
                                if (StringUtils.isEmpty(data.getValue())) {
                                    throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                                }
                            }
                        }
                    }
                    intervalTimePeriodTelemetry.add(intervalTelemetryData);
                }
                //学习段
                telemetryDto.setStartTime(learnMultiTerminalTime.get(i).getStartTime());
                telemetryDto.setEndTime(learnMultiTerminalTime.get(i).getEndTime());
                Map<String, List<TelemetryData>> telemetryData = selectTelemetryData(telemetryDto);

                //判断是否存在空值
                for (Map.Entry<String, List<TelemetryData>> map : telemetryData.entrySet()) {
                    List<TelemetryData> list = map.getValue();
                    if (!CollectionUtils.isEmpty(list)) {
                        for (TelemetryData data : list) {
                            if (StringUtils.isEmpty(data.getValue())) {
                                throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                            }
                        }
                    }
                }
                learnTelemetryDataList.add(telemetryData);
            }
        } else {
            throw new HealthException("学习段长度小于2，无法产生间隙段");
        }
        caseOneDTO.setLearnClearanceMultiTerminalTime(intervalTimePeriodList);
        //学习间隙段遥测
        telemetryMap.put("learnIntervalTimePeriodTelemetry", intervalTimePeriodTelemetry);
        //学习段遥测
        telemetryMap.put("learnTelemetryDataList", learnTelemetryDataList);


        //任务计划段-遥测
        List<Map<String, List<TelemetryData>>> taskTelemetryDataList = new ArrayList<>();
        ArrayList<TimeDto> taskTimeList = new ArrayList<>();
        //任务计划间隔间隔段-遥测
        List<Map<String, List<TelemetryData>>> taskIntervalTelemetry = new ArrayList<>();
        ArrayList<TimeDto> taskIntervalTimeList = new ArrayList<>();
        //获取A B C D E 标识
//        CheckResult<Object> appCheckResult = null;
//        DataSourceVo appDataSourceVo = new DataSourceVo();
//        StringBuilder appSql = new StringBuilder().append("select tdrsinternalcode from app_zj_tdrsinfodic where  tdrsname = '").append(caseOneDTO.getSatelliteName()).append("'");
//        appDataSourceVo.setSql(appSql.toString());
//        appDataSourceVo.setDbKey("HOLOGRES");
//        appCheckResult = dataQualityService.excuteRunSql(appDataSourceVo);
//        Map appData = (Map) appCheckResult.getData();
//        AppZjTdrsinfodic appZjTdrsinfodics = JSON.parseObject(JSON.toJSONString(appData.get("data")), AppZjTdrsinfodic.class);

        //从t02_tb_datatransmissionplan表里获取检测时间段的数据
        DataSourceVo dataSourceVo = new DataSourceVo();
        StringBuilder sql = new StringBuilder().append("select * from t02_tb_datatransmissionplan where  servicestarttime >= '")
                .append(new Timestamp(caseOneVo.getVerifyTime().getStartTime().getTime())).append("' and ").append(" servicestarttime <='")
                .append(new Timestamp(caseOneVo.getVerifyTime().getEndTime().getTime())).append("'").append(" and ").append(" state!= 'deleted' ");
        //                .append(" and ").append("satellite_id = '").append(appZjTdrsinfodics.getTdrsinternalcode()).append("'");
        String satelliteNewId = satelliteNodeMapper.getSatelliteCode(caseOneVo.getSatelliteCode());
        if (null != satelliteNewId) {
            sql .append(" and ").append("satellite_id = '").append(satelliteNewId).append("'");
        }
        dataSourceVo.setSql(sql.toString());
        dataSourceVo.setDbKey("HOLOGRES");
        log.info("单参数诊断调用门户接口路径：" + dsParam.getGetRunSql());
        log.info("单参数诊断提供入参：" + sql);
        CheckResult<Object> checkResult = null;
        try {
            checkResult = dataQualityService.excuteRunSql(dataSourceVo);
        } catch (Exception e) {
            faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"入参和地址异常","检查入参和地址是否正确");
            throw new HealthException("请检查入参和地址是否正确");
        }
        log.info("单参数诊断调用门户接口成功");
        Map data = (Map) checkResult.getData();
        List<TbDatatransmissionplan> datatransmissionplans = JSON.parseArray(JSON.toJSONString(data.get("data")), TbDatatransmissionplan.class);
        log.info("获取到门户提供的原始数据", datatransmissionplans);

        List<TbDatatransmissionplan> dataMissionPlanList = new ArrayList<>();
        List<TbDatatransmissionplan> tbDatatransmissionplanList = new ArrayList<>();
        if (CollUtil.isNotEmpty(datatransmissionplans)) {
            //处理获取数据时间字段并按照格式化之后的时间进行排序
            List<TbDatatransmissionplan> distinctData = new ArrayList<>(datatransmissionplans.stream().collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TbDatatransmissionplan::getServicestarttime)))));
            distinctData.forEach(item -> item.setServicestarttime(item.getServicestarttime().substring(0, 19).replace("T", " ")));
            dataMissionPlanList = distinctData.stream().sorted(Comparator.comparing(x -> DateUtil.parse(x.getServicestarttime(), "yyyy-MM-dd HH:mm:ss"))).collect(Collectors.toList());


            //处理捕跟结束时间格式化
            for (TbDatatransmissionplan tbDatatransmissionplan : dataMissionPlanList) {
                String servicestarttime = tbDatatransmissionplan.getServicestarttime();
                String serviceretaintime = tbDatatransmissionplan.getServiceretaintime();
                if (StrUtil.isEmpty(servicestarttime) && StrUtil.isEmpty(serviceretaintime)) {
                    throw new HealthException("捕跟开始时间，计划服务时长中存在空值数据,请确认门户提供的数据是否正常");
                }
                Date missionRetailEndTime = (Date) executeServiceRetailTime(DateUtil.parse(servicestarttime, "yyyy-MM-dd HH:mm:ss"), serviceretaintime).getData();
                TbDatatransmissionplan convert = BeanUtil.copyBean(tbDatatransmissionplan, TbDatatransmissionplan.class);
                convert.setServiceendtime(missionRetailEndTime);
                tbDatatransmissionplanList.add(convert);
            }

            //处理边界值问题
            long verifyStartTime = caseOneDTO.getVerifyTime().getStartTime().getTime();
            long verifyEndTime = caseOneDTO.getVerifyTime().getEndTime().getTime();
            tbDatatransmissionplanList.get(0).setServicestarttime(DateUtil.format(new Date(verifyStartTime), "yyyy-MM-dd HH:mm:ss"));
            tbDatatransmissionplanList.get(tbDatatransmissionplanList.size() - 1).setServiceendtime(new Date(verifyEndTime));

            if (tbDatatransmissionplanList.size() >= 2) {
                for (int i = 0; i < tbDatatransmissionplanList.size(); i++) {
                    //任务段
                    DateTime servicestarttime = DateUtil.parse(tbDatatransmissionplanList.get(i).getServicestarttime(), "yyyy-MM-dd HH:mm:ss");
                    Date taskEndTime = tbDatatransmissionplanList.get(i).getServiceendtime();
                    telemetryDto.setStartTime(servicestarttime);
                    telemetryDto.setEndTime(taskEndTime);
                    taskTimeList.add(TimeDto.builder().startTime(servicestarttime).endTime(taskEndTime).build());
                    Map<String, List<TelemetryData>> taskPlanTelemetry = selectTelemetryData(telemetryDto);

                    //判断遥测中是否存在空值
                    for (Map.Entry<String, List<TelemetryData>> map : taskPlanTelemetry.entrySet()) {
                        List<TelemetryData> list = map.getValue();
                        if (!CollectionUtils.isEmpty(list)) {
                            for (TelemetryData telemetryData : list) {
                                if (StringUtils.isEmpty(telemetryData.getValue())) {
                                    throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                                }
                            }
                        }
                    }
                    taskTelemetryDataList.add(taskPlanTelemetry);

                    if (i < tbDatatransmissionplanList.size() - 1) {
                        //任务间隙段
                        Date taskIntervalStartTime = taskEndTime;
                        String taskIntervalEndTimeOriginal = tbDatatransmissionplanList.get(i + 1).getServicestarttime();
                        DateTime taskIntervalEndTime = DateUtil.parse(taskIntervalEndTimeOriginal, "yyyy-MM-dd HH:mm:ss");
                        telemetryDto.setStartTime(taskIntervalStartTime);
                        telemetryDto.setEndTime(taskIntervalEndTime);
                        Map<String, List<TelemetryData>> taskIntervalTelemetryData = selectTelemetryData(telemetryDto);
                        //判断遥测中是否存在空值
                        for (Map.Entry<String, List<TelemetryData>> map : taskIntervalTelemetryData.entrySet()) {
                            List<TelemetryData> list = map.getValue();
                            if (!CollectionUtils.isEmpty(list)) {
                                for (TelemetryData telemetryData : list) {
                                    if (StringUtils.isEmpty(telemetryData.getValue())) {
                                        throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                                    }
                                }
                            }
                        }
                        taskIntervalTelemetry.add(taskIntervalTelemetryData);


                        taskIntervalTimeList.add(TimeDto.builder().startTime(taskIntervalStartTime).endTime(taskIntervalEndTime).build());
                        caseOneDTO.setTaskMultiterminalTime(taskTimeList);
                        caseOneDTO.setTaskClearanceMultiterminalTime(taskIntervalTimeList);
                        telemetryMap.put("taskTelemetryDataList", taskTelemetryDataList);
                        telemetryMap.put("taskIntervalTelemetry", taskIntervalTelemetry);
                    }
                }
            } else {
                throw new HealthException("从任务计划表里查询到落到检测时间范围数据总数小于2,无法产生间隙数据");
            }
            caseOneDTO.setTelemetryDataList(telemetryMap);
            return caseOneDTO;

        } else {
            throw new HealthException("该时间段内没有查询到任务计划数据");
        }
    }

    /**
     * 单参数诊断上线
     *
     * @param taskChildInfo 子任务对象
     * @param taskInfo      任务对象
     * @param caseOneDTO    单参数入参
     */
    public void singleParameterDiagnosisOnline(TaskChildInfo taskChildInfo, TaskInfo taskInfo, CaseOneDTO caseOneDTO) throws UnknownHostException {
        HttpResponse postResponse = null;
        try {
            postResponse = HttpUtil.createRequest(Method.POST, algorithmParam.getSingleDetectAlgorithm()).body(JSON.toJSONString(caseOneDTO)).execute();
            if (postResponse.getStatus() != HttpStatus.HTTP_OK) {
                // 返回为空默认为解析失败
                throw new HealthException("算法调用失败");
            }
            JSONArray jsonArrays = null;
            JSONObject map = null;
            try {
                jsonArrays = JSONArray.parseArray(postResponse.body());
            } catch (Exception e) {
                map = JSONObject.parseObject(postResponse.body(), JSONObject.class);
                if (map.getInteger(HealthManagerConstant.STATUS_CODE).equals(ResultEnum.FAIL.getCode())) {
                    faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"调用算法失败","调用算法执行异常");
                    throw new HealthException(map.getString("msg"));
                }
            }
            List parseObject = JSONObject.parseObject(postResponse.body(), List.class);
            SingleParameterDiagnosisVo singleParameterDiagnosisVo = JSON.parseObject(JSON.toJSONString(parseObject.get(0)), SingleParameterDiagnosisVo.class);

            List<SingleParameterDiagnosisVo.downMissionDTO> missionGraphDTOList = singleParameterDiagnosisVo.getDownMissionDTOList();

            ArrayList<MultiparatersDTO> list = new ArrayList<>();
            if (CollUtil.isNotEmpty(missionGraphDTOList)) {
                for (SingleParameterDiagnosisVo.downMissionDTO missionGraphDTO : missionGraphDTOList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(missionGraphDTO.getTime());
                    multiparatersDTO.setValue(missionGraphDTO.getValue());
                    multiparatersDTO.setType("missiongraph");
                    list.add(multiparatersDTO);
                }
                taskChildInfo.setDataSituation("(" + missionGraphDTOList.get(0).getTime() + "," + missionGraphDTOList.get(missionGraphDTOList.size() - 1).getTime() + ")");
                taskChildInfo.setStatus(TaskStatusEnum.DONE.getCode());
                taskChildInfo.setMsg(singleParameterDiagnosisVo.getMsg());
                taskChildInfoService.updateByIdSelective(taskChildInfo);
            }

            List<SingleParameterDiagnosisVo.downRestDTO> restGraphDTOList = singleParameterDiagnosisVo.getDownRestDTOList();
            if (CollUtil.isNotEmpty(restGraphDTOList)) {
                for (SingleParameterDiagnosisVo.downRestDTO restGraphDTO : restGraphDTOList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(restGraphDTO.getTime());
                    multiparatersDTO.setValue(restGraphDTO.getValue());
                    multiparatersDTO.setType("restgraph");
                    list.add(multiparatersDTO);
                }
            }

            //执行上端
            List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionUpList = singleParameterDiagnosisVo.getDetectMissionUp();
            if (CollUtil.isNotEmpty(detectMissionUpList)) {
                for (SingleParameterDiagnosisVo.downMissionDTO restGraphDTO : detectMissionUpList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(restGraphDTO.getTime());
                    multiparatersDTO.setValue(restGraphDTO.getValue());
                    multiparatersDTO.setType("detectMissionUp");
                    list.add(multiparatersDTO);
                }
            }

            //执行下端
            List<SingleParameterDiagnosisVo.downMissionDTO> detectMissionDownList = singleParameterDiagnosisVo.getDetectMissionDown();
            if (CollUtil.isNotEmpty(detectMissionDownList)) {
                for (SingleParameterDiagnosisVo.downMissionDTO restGraphDTO : detectMissionDownList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(restGraphDTO.getTime());
                    multiparatersDTO.setValue(restGraphDTO.getValue());
                    multiparatersDTO.setType("detectMissionDown");
                    list.add(multiparatersDTO);
                }
            }

            //间隙上端
            List<SingleParameterDiagnosisVo.downMissionDTO> detectRestUpList = singleParameterDiagnosisVo.getDetectRestUp();
            if (CollUtil.isNotEmpty(detectRestUpList)) {
                for (SingleParameterDiagnosisVo.downMissionDTO restGraphDTO : detectRestUpList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(restGraphDTO.getTime());
                    multiparatersDTO.setValue(restGraphDTO.getValue());
                    multiparatersDTO.setType("detectRestUp");
                    list.add(multiparatersDTO);
                }
            }


            //间隙下端
            List<SingleParameterDiagnosisVo.downMissionDTO> detectRestDownList = singleParameterDiagnosisVo.getDetectRestDown();
            if (CollUtil.isNotEmpty(detectRestDownList)) {
                for (SingleParameterDiagnosisVo.downMissionDTO restGraphDTO : detectRestDownList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(restGraphDTO.getTime());
                    multiparatersDTO.setValue(restGraphDTO.getValue());
                    multiparatersDTO.setType("detectRestDown");
                    list.add(multiparatersDTO);
                }
            }




            //执行段散点
            List<SingleParameterDiagnosisVo.ScatterDTO> scatterDTOList = singleParameterDiagnosisVo.getScatterMission();
            if (CollUtil.isNotEmpty(scatterDTOList)) {
                for (SingleParameterDiagnosisVo.ScatterDTO scatterDTO : scatterDTOList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(scatterDTO.getTime());
                    multiparatersDTO.setValue(Double.valueOf(scatterDTO.getValue()));
                    multiparatersDTO.setType("scatterMission");
                    list.add(multiparatersDTO);
                }
            }
            List<SingleParameterDiagnosisVo.ScatterDTO> scatterRestList = singleParameterDiagnosisVo.getScatterRest();
            if (CollUtil.isNotEmpty(scatterRestList)) {
                for (SingleParameterDiagnosisVo.ScatterDTO scatterDTO : scatterRestList) {
                    MultiparatersDTO multiparatersDTO = new MultiparatersDTO();
                    multiparatersDTO.setTaskId(taskChildInfo.getTaskId());
                    multiparatersDTO.setTaskChildId(taskChildInfo.getId());
                    multiparatersDTO.setSateCode(taskChildInfo.getSatelliteCode());
                    multiparatersDTO.setParamCode(taskInfo.getParams());
                    multiparatersDTO.setTime(scatterDTO.getTime());
                    multiparatersDTO.setValue(Double.valueOf(scatterDTO.getValue()));
                    multiparatersDTO.setType("scatterRest");
                    list.add(multiparatersDTO);
                }
            }

            faultInfoMapper.insertDiagnoseSingleParameterDiagnosis(list);

            ArrayList<MultiparatersDTO> rightTipsArrayList = new ArrayList<>();
            List<SingleParameterDiagnosisVo.MissionTrainResultDTO> missionTrainResultDTO = singleParameterDiagnosisVo.getMissionTrainResult();
            if (CollUtil.isNotEmpty(missionTrainResultDTO)) {
                for (SingleParameterDiagnosisVo.MissionTrainResultDTO trainResultDTO : missionTrainResultDTO) {
                    MultiparatersDTO missionTrain = new MultiparatersDTO();
                    missionTrain.setTaskId(taskChildInfo.getTaskId());
                    missionTrain.setTaskChildId(taskChildInfo.getId());
                    missionTrain.setSateCode(taskChildInfo.getSatelliteCode());
                    missionTrain.setParamCode(taskInfo.getParams());
                    missionTrain.setName(trainResultDTO.getName());
                    missionTrain.setValue(trainResultDTO.getValue());
                    missionTrain.setType("missiontrainresult");
                    rightTipsArrayList.add(missionTrain);
                }
            }


            List<SingleParameterDiagnosisVo.RestTrainResultDTO> restTrainResultDTOList = singleParameterDiagnosisVo.getRestTrainResult();
            if (CollUtil.isNotEmpty(restTrainResultDTOList)) {
                for (SingleParameterDiagnosisVo.RestTrainResultDTO restTrainResultDTO : restTrainResultDTOList) {
                    MultiparatersDTO restTrainResult = new MultiparatersDTO();
                    restTrainResult.setTaskId(taskChildInfo.getTaskId());
                    restTrainResult.setTaskChildId(taskChildInfo.getId());
                    restTrainResult.setSateCode(taskChildInfo.getSatelliteCode());
                    restTrainResult.setParamCode(taskInfo.getParams());
                    restTrainResult.setName(restTrainResultDTO.getName());
                    restTrainResult.setValue(restTrainResultDTO.getValue());
                    restTrainResult.setType("resttrainresult");
                    rightTipsArrayList.add(restTrainResult);
                }
            }

            List<SingleParameterDiagnosisVo.MissionDetectResultDTO> missionDetectResult = singleParameterDiagnosisVo.getMissionDetectResult();
            if (CollUtil.isNotEmpty(missionDetectResult)) {
                for (SingleParameterDiagnosisVo.MissionDetectResultDTO missionDetectResultDTO : missionDetectResult) {
                    MultiparatersDTO missionDetect = new MultiparatersDTO();
                    missionDetect.setTaskId(taskChildInfo.getTaskId());
                    missionDetect.setTaskChildId(taskChildInfo.getId());
                    missionDetect.setSateCode(taskChildInfo.getSatelliteCode());
                    missionDetect.setParamCode(taskInfo.getParams());
                    missionDetect.setName(missionDetectResultDTO.getName());
                    missionDetect.setValue(missionDetectResultDTO.getValue());
                    missionDetect.setType("missiondetectresult");
                    rightTipsArrayList.add(missionDetect);
                }
            }

            List<SingleParameterDiagnosisVo.RestDetectResultDTO> restDetectResult = singleParameterDiagnosisVo.getRestDetectResult();
            if (CollUtil.isNotEmpty(restDetectResult)) {
                for (SingleParameterDiagnosisVo.RestDetectResultDTO restDetectResultDTO : restDetectResult) {
                    MultiparatersDTO restDetect = new MultiparatersDTO();
                    restDetect.setTaskId(taskChildInfo.getTaskId());
                    restDetect.setTaskChildId(taskChildInfo.getId());
                    restDetect.setSateCode(taskChildInfo.getSatelliteCode());
                    restDetect.setParamCode(taskInfo.getParams());
                    restDetect.setName(restDetectResultDTO.getName());
                    restDetect.setValue(restDetectResultDTO.getValue());
                    restDetect.setType("restdetectresult");
                    rightTipsArrayList.add(restDetect);
                }
            }
            if(!CollectionUtils.isEmpty(rightTipsArrayList)){
                faultInfoMapper.insertDiagnoseSingleParameterDiagnosis(rightTipsArrayList);
            }

        } catch (Exception e) {
            taskChildInfo.setDataSituation("无");
            taskChildInfo.setStatus(TaskStatusEnum.ABNORMAL.getCode());
            taskChildInfoService.updateByIdSelective(taskChildInfo);
            log.error("任务:{} 执行失败! 异常信息:{}", taskChildInfo.getName(), ExceptionUtil.getMessage(e));
            e.printStackTrace();
            faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"任务执行失败","任务执行异常");
            throw new HealthException("遥测数据为空");
        }

    }


    /**
     * 子任务 查看组装遥测数据
     *
     * @param paramSplit         参数代号
     * @param taskChildInfo      子任务对象
     * @param length             长度
     * @param type               类型
     * @param trailTelemetryList 手动试算遥测数据
     * @return Map<String, Object>
     */
    public Map<String, Object> assembleTelemetryListForKandTwoAndFeature(String[] paramSplit, TaskChildInfo taskChildInfo, Integer length, String type, List<Map<String, Object>> trailTelemetryList,Integer originalDataSources) {
        HashMap<String, Object> finalMap = new HashMap<>(2);
        Map<String, Object> args = new LinkedHashMap<>();
        List<Map<String, Object>> telemetryList = new ArrayList<>();
        if (CollUtil.isNotEmpty(trailTelemetryList) && BeanUtil.isEmpty(taskChildInfo)) {
            telemetryList = trailTelemetryList;
        } else {
            for (String paramCode : paramSplit) {
                // 查询遥测数据
                TelemetryDto telemetryDto = new TelemetryDto();
                telemetryDto.setSatelliteCode(taskChildInfo.getSatelliteCode());
                telemetryDto.setParamCodes((new String[]{paramCode}));
                telemetryDto.setStartTime(taskChildInfo.getStartTime());
                telemetryDto.setEndTime(taskChildInfo.getEndTime());
                Map<String, List<TelemetryData>> map = new HashMap<>(16);
                /*1 ：预处理平滑后的遥测数据 ，其他：原始遥测数据*/
                if(originalDataSources != null && 1 == originalDataSources){
                    map = selectPrePhData(telemetryDto);
                }else{
                    map = selectTelemetryData(telemetryDto);
                }
                List<TelemetryData> ycList = map.get(paramCode);
                List<ArrayList<String>> collect = ycList.stream().map(x -> CollUtil.newArrayList(x.getTime(), x.getValue())).collect(Collectors.toList());
                args.put(paramCode, ycList);
                Map<String, Object> telemetry = new LinkedHashMap<>();
                telemetry.put("name", paramCode);
                telemetry.put("data", collect);
                telemetryList.add(telemetry);
            }
        }

        //获取到双参数遥测的最小长度
        if (StrUtil.isNotEmpty(type) && length == null && type.equals(MultiParameterEnum.TWOPARAMETERDIAGNOSISALGORITHM.getCode())) {
            ArrayList<Integer> list = new ArrayList<>();
            if (CollUtil.isNotEmpty(telemetryList)) {
                for (Map<String, Object> map : telemetryList) {
                    ArrayList xlist = (ArrayList) map.get("data");
                    list.add(xlist.size());
                }
                Collections.sort(list);
                length = list.get(0);
            }
        }

        //x轴
        Set<Object> xAxis = new LinkedHashSet<>();
        //截图长度后的遥测
        ArrayList<Object> telemetryArrayList = new ArrayList<>();
        int j = 1;
        //排序拿到遥测长度的最小值，截取遥测长度一致，
        if (CollUtil.isNotEmpty(telemetryList) && length != null && StrUtil.isNotEmpty(type)) {
            for (String paramCode : paramSplit) {
                for (Map<String, Object> map : telemetryList) {
                    if (paramCode.equals(map.get("name"))) {
                        ArrayList dataList = (ArrayList) map.get("data");
                        HashMap<String, Object> telemetryMap = new HashMap<>(2);
                        telemetryMap.put("name", paramCode);
                        if (dataList.size() != length) {
                            ArrayList collect = (ArrayList) dataList.stream().limit(length).collect(Collectors.toList());
                            telemetryMap.put("data", collect);
                            telemetryArrayList.add(telemetryMap);
                            if (j == 1) {
                                for (Object o : collect) {
                                    List list1 = (List) o;
                                    xAxis.add(list1.get(0));
                                }
                                j++;
                            }
                        } else {
                            if (j == 1) {
                                for (Object o : dataList) {
                                    List list1 = (List) o;
                                    xAxis.add(list1.get(0));
                                }
                                j++;
                            }
                            telemetryMap.put("data", dataList);
                            telemetryArrayList.add(telemetryMap);
                        }

                    }
                }
            }
        }
        finalMap.put("xLineAxis", xAxis);
        finalMap.put("xAxis", xAxis);
        if (CollUtil.isNotEmpty(telemetryList) && length != null && StrUtil.isNotEmpty(type)) {
            finalMap.put("telemetryList", telemetryArrayList);
        } else {
            finalMap.put("telemetryList", telemetryList);
        }
        finalMap.put("args", args);
        return finalMap;
    }


    /**
     * 重组算法返回的JSON数据
     *
     * @param algorithmParseObject JSON数据
     * @return AlgorithmParseDTO
     */
    public AlgorithmParseDTO reassembleParseData(JSONObject algorithmParseObject) {
        JSONArray anomalyObject = algorithmParseObject.getObject("anomaly", JSONArray.class);
        ArrayList<ArrayList<AlgorithmParseDTO.AnomalyDTO>> arrayList = new ArrayList<>();
        AlgorithmParseDTO parseDTO = new AlgorithmParseDTO();
        for (Object o : anomalyObject) {
            JSONObject objectList = JSONObject.parseObject(JSON.toJSONString(o), JSONObject.class);
            Set<String> keySet = objectList.keySet();
            for (String key : keySet) {
                JSONArray jsonArray = objectList.getObject(key, JSONArray.class);
                ArrayList<AlgorithmParseDTO.AnomalyDTO> list = new ArrayList<>();
                for (Object object : jsonArray) {
                    AlgorithmParseDTO.AnomalyDTO anomalyDTO = JSONObject.parseObject(JSON.toJSONString(object), AlgorithmParseDTO.AnomalyDTO.class);
                    anomalyDTO.setName(key);
                    list.add(anomalyDTO);
                }
                arrayList.add(list);
                parseDTO.setAnomaly(arrayList);
            }
        }

        JSONArray valueParse = algorithmParseObject.getObject("value", JSONArray.class);
        ArrayList<AlgorithmParseDTO.ValueDTO> valueDtoArrayList = new ArrayList<>();
        for (Object o : valueParse) {
            JSONObject objectList = JSONObject.parseObject(JSON.toJSONString(o), JSONObject.class);
            String time = objectList.getString("time");
            Double value = objectList.getDouble("value");
            AlgorithmParseDTO.ValueDTO valueDTO = new AlgorithmParseDTO.ValueDTO();
            valueDTO.setTime(time);
            valueDTO.setValue(value);
            valueDtoArrayList.add(valueDTO);
        }
        parseDTO.setValue(valueDtoArrayList);


        JSONObject graphList = algorithmParseObject.getObject("graph", JSONObject.class);
        Set<String> keySet = graphList.keySet();
        ArrayList<ArrayList<AlgorithmParseDTO.GraphDTO>> arrayLists = new ArrayList<>();
        for (String key : keySet) {
            ArrayList<AlgorithmParseDTO.GraphDTO> graphDtoArrayList = new ArrayList<>();
            if ("threshold".equals(key)) {
                JSONArray jsonArray = graphList.getObject(key, JSONArray.class);
                for (Object o : jsonArray) {
                    JSONArray array = JSONObject.parseObject(JSON.toJSONString(o), JSONArray.class);
                    for (Object object : array) {
                        AlgorithmParseDTO.GraphDTO graphDTO = JSONObject.parseObject(JSON.toJSONString(object), AlgorithmParseDTO.GraphDTO.class);
                        graphDTO.setName(key);
                        graphDtoArrayList.add(graphDTO);
                    }

                }
                arrayLists.add(graphDtoArrayList);
                parseDTO.setGraph(arrayLists);
            } else {
                JSONArray jsonArray = graphList.getObject(key, JSONArray.class);
                for (Object o : jsonArray) {
                    AlgorithmParseDTO.GraphDTO graphDTO = JSONObject.parseObject(JSON.toJSONString(o), AlgorithmParseDTO.GraphDTO.class);
                    graphDTO.setName(key);
                    graphDtoArrayList.add(graphDTO);
                }
                arrayLists.add(graphDtoArrayList);
                parseDTO.setGraph(arrayLists);
            }
        }

        String msgList = algorithmParseObject.getString("msg");
        parseDTO.setMsg(msgList);
        String paramCodeList = algorithmParseObject.getString("param_code");
        parseDTO.setParamCode(paramCodeList);
        return parseDTO;

    }

    /**
     * 处理计划服务时长字段时间
     *
     * @param servicestarttime  开始时间
     * @param serviceretailtime 计划服务时长 例:081514
     * @return CheckResult<Object>
     */
    public static CheckResult<Object> executeServiceRetailTime(Date servicestarttime, String serviceretailtime) {
        String[] split = serviceretailtime.split("");
        Date taskEndTime = null;
        long endTime = 0L;
        try {
            long startTime = servicestarttime.getTime();
            for (int j = 0; j < split.length; j++) {
                if (j < 2) {
                    if (j == 0) {
                        long s1 = Integer.parseInt(split[j]) * 10 * 60 * 60 * 1000;
                        endTime += s1;
                    } else {
                        long s1 = Integer.parseInt(split[j]) * 60 * 60 * 1000;
                        endTime += s1;
                    }
                } else if (j > 1 && j < 4) {
                    if (j == 2) {
                        long s2 = Integer.parseInt(split[j]) * 10 * 60 * 1000;
                        endTime += s2;
                    } else {
                        long s2 = Integer.parseInt(split[j]) * 60 * 1000;
                        endTime += s2;
                    }

                } else {
                    if (j == 4) {
                        long s3 = Integer.parseInt(split[j]) * 10 * 1000;
                        endTime += s3;
                    }
                    long s3 = Integer.parseInt(split[j]) * 1000;
                    endTime += s3;
                }
            }
            taskEndTime = new Date(startTime + endTime);
            return CheckResult.success(taskEndTime);
        } catch (Exception e) {
            throw new HealthException("时间格式化异常");
        }
    }


//    /**
//     * 补充缺失数据
//     * @param list 待补充集合
//     * @return 补充完的集合
//     */
//    public  Map<String, List<TelemetryData>> addDataToListMap(Map<String, List<TelemetryData>> list) {
//        Map<String, List<TelemetryData>> result =new HashMap<>();
//        if(!CollectionUtils.isEmpty(list)){
//            for(Map.Entry<String, List<TelemetryData>> map: list.entrySet()){
//                List<TelemetryData> resList=new ArrayList<>();
//                List<TelemetryData> tList=map.getValue();
//                if(!CollectionUtils.isEmpty(tList)){
//                    if(tList.size()>1){
//                        for(int i=0;i<tList.size()-1;i++){
//                            TelemetryData dto=tList.get(i);
//                            TelemetryData dto2=tList.get(i+1);
//                            String time1 = dto.getTime();
//                            String time2 = dto2.getTime();
//                            time1= ConvertUtils.formatTime(time1);
//                            time2=ConvertUtils.formatTime(time2);
//                            DateTimeFormatter formatter= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
//                            LocalDateTime timeFormatter1 = LocalDateTime.parse(time1, formatter);
//                            LocalDateTime timeFormatter2 = LocalDateTime.parse(time2, formatter);
//                            LocalDateTime timeFormatter3=timeFormatter1.plus(AMOUNT_TO_ADD, ChronoUnit.MILLIS);
//                            dto.setTime(time1);
//                            resList.add(dto);
//                            if(timeFormatter2.isAfter(timeFormatter3)){
//                                String startLocalDate = timeFormatter3.toLocalDate() + " " + timeFormatter3.toLocalTime();
//                                if(16==startLocalDate.length()){
//                                    startLocalDate=startLocalDate+":00";
//                                }
//                                if(!startLocalDate.contains(".")){
//                                    startLocalDate=startLocalDate+".000";
//                                }
//                                TelemetryData res=new TelemetryData();
//                                res.setTime(startLocalDate);
//                                resList.add(res);
//                            }
//                        }
//                        TelemetryData telemetryData = tList.get(tList.size() - 1);
//                        telemetryData.setTime(ConvertUtils.formatTime(telemetryData.getTime()));
//                        resList.add(telemetryData);
//                    }else{
//                        TelemetryData telemetryData = tList.get(0);
//                        telemetryData.setTime(ConvertUtils.formatTime(telemetryData.getTime()));
//                        resList.add(telemetryData);
//                    }
//                }
//                result.put(map.getKey(),resList);
//            }
//
//        }
//        return result;
//    }


}

